diff options
author | Kjell Wooding <kjell@cvs.openbsd.org> | 1999-12-15 05:20:28 +0000 |
---|---|---|
committer | Kjell Wooding <kjell@cvs.openbsd.org> | 1999-12-15 05:20:28 +0000 |
commit | 0d8d81d8f58d6f5eae36373c100a2562a3d9c879 (patch) | |
tree | b3707c6aa857b4476407ab2400656c7c43045937 /sbin | |
parent | b31112257bf9b07ac5f126920d34834e580e789f (diff) |
Import of Darren Reed's IPFilter 3.3.4, including OpenBSD patches.
Many, many enhancements and improvements, including new in-kernel
proxies, enhancements to logging, and many bugfixes.
Note: Man pages have not yet been re-converted to mdoc.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ipf/Makefile | 4 | ||||
-rw-r--r-- | sbin/ipf/ipf.c | 132 | ||||
-rw-r--r-- | sbin/ipf/ipf.h | 52 | ||||
-rw-r--r-- | sbin/ipf/opt.c | 10 | ||||
-rw-r--r-- | sbin/ipf/parse.c | 606 | ||||
-rw-r--r-- | sbin/ipfstat/Makefile | 4 | ||||
-rw-r--r-- | sbin/ipfstat/fils.c | 182 | ||||
-rw-r--r-- | sbin/ipfstat/kmem.c | 39 | ||||
-rw-r--r-- | sbin/ipfstat/kmem.h | 5 | ||||
-rw-r--r-- | sbin/ipnat/Makefile | 4 | ||||
-rw-r--r-- | sbin/ipnat/ipnat.c | 663 |
11 files changed, 801 insertions, 900 deletions
diff --git a/sbin/ipf/Makefile b/sbin/ipf/Makefile index 80354684536..4940b8564ee 100644 --- a/sbin/ipf/Makefile +++ b/sbin/ipf/Makefile @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile,v 1.5 1999/02/07 00:48:28 deraadt Exp $ +# $OpenBSD: Makefile,v 1.6 1999/12/15 05:20:23 kjell Exp $ PROG= ipf MAN= ipf.8 ipf.4 ipf.5 -SRCS= ipf.c parse.c opt.c +SRCS= ipf.c parse.c opt.c facpri.c .include <bsd.prog.mk> diff --git a/sbin/ipf/ipf.c b/sbin/ipf/ipf.c index eaaf94e6094..bf2517b13af 100644 --- a/sbin/ipf/ipf.c +++ b/sbin/ipf/ipf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipf.c,v 1.19 1999/07/06 19:06:42 kjell Exp $ */ +/* $OpenBSD: ipf.c,v 1.20 1999/12/15 05:20:24 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -35,20 +35,18 @@ #include <netdb.h> #include <arpa/nameser.h> #include <resolv.h> -#if defined(__OpenBSD__) -# include <netinet/ip_fil_compat.h> -#else -# include <netinet/ip_compat.h> -#endif +#include <netinet/ip_fil_compat.h> #include <netinet/ip_fil.h> +#include <netinet/ip_nat.h> +#include <netinet/ip_state.h> #include "ipf.h" +#include <netinet/ipl.h> #if !defined(lint) static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipf.c,v 1.19 1999/07/06 19:06:42 kjell Exp $"; +static const char rcsid[] = "@(#)$Id: ipf.c,v 1.20 1999/12/15 05:20:24 kjell Exp $"; #endif -static void frsync __P((void)); #if SOLARIS static void blockunknown __P((void)); #endif @@ -60,6 +58,7 @@ extern char *optarg; extern int optind; extern int optreset; +void frsync __P((void)); void zerostats __P((void)); int main __P((int, char *[])); @@ -74,24 +73,28 @@ static int opendevice __P((char *)); static void closedevice __P((void)); static char *getline __P((char *, size_t, FILE *)); static char *ipfname = IPL_NAME; +static void usage __P((void)); +static void showversion __P((void)); +static int get_flags __P((void)); #if SOLARIS -#define OPTS "AdDEf:F:Il:noPrsUvyzZ" +#define OPTS "AdDEf:F:Il:noPrsUvVyzZ" #else -#define OPTS "AdDEf:F:Il:noPrsvyzZ" +#define OPTS "AdDEf:F:Il:noPrsvVyzZ" #endif -void usage() +static void usage() { #if SOLARIS - fprintf(stderr, "usage: ipf [-AdDEInorsUvyzZ] [-l block|pass|nomatch] " + fprintf(stderr, "usage: ipf [-AdDEInoPrsUvVyzZ] %s %s %s\n", #else - fprintf(stderr, "usage: ipf [-AdDEInorsvyzZ] [-l block|pass|nomatch] " + fprintf(stderr, "usage: ipf [-AdDEInoPrsvVyzZ] %s %s %s\n", #endif - "[-F i|o|a|s|S] [-f filename]\n"); + "[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]"); exit(1); } + int main(argc,argv) int argc; char *argv[]; @@ -154,6 +157,9 @@ char *argv[]; case 'v' : opts |= OPT_VERBOSE; break; + case 'V' : + showversion(); + break; case 'y' : frsync(); break; @@ -198,6 +204,18 @@ static void closedevice() } +static int get_flags() +{ + int i; + + if ((opendevice(ipfname) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) { + perror("SIOCFRENB"); + return 0; + } + return i; +} + + static void set_state(enable) u_int enable; { @@ -213,13 +231,17 @@ char *name, *file; FILE *fp; char line[513], *s; struct frentry *fr; - u_int add = SIOCADAFR, del = SIOCRMAFR; + u_int add, del; + int linenum = 0; (void) opendevice(ipfname); 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); @@ -235,6 +257,7 @@ char *name, *file; } while (getline(line, sizeof(line), fp)) { + linenum++; /* * treat CR as EOL. LF is converted to NUL by getline(). */ @@ -252,7 +275,7 @@ char *name, *file; if (opts & OPT_VERBOSE) (void)fprintf(stderr, "[%s]\n", line); - fr = parse(line); + fr = parse(line, linenum); (void)fflush(stdout); if (fr) { @@ -339,13 +362,12 @@ FILE *file; static void packetlogon(opt) char *opt; { - int err, flag = 0; - - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - if ((err = ioctl(fd, SIOCGETFF, &flag))) - perror("ioctl(SIOCGETFF)"); + int flag, err; - printf("log flag is currently %#x\n", flag); + err = get_flags(); + if (err != 0) { + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) + printf("log flag is currently %#x\n", flag); } flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK); @@ -370,9 +392,7 @@ char *opt; perror("ioctl(SIOCSETFF)"); if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - if ((err = ioctl(fd, SIOCGETFF, &flag))) - perror("ioctl(SIOCGETFF)"); - + flag = get_flags(); printf("log flag is now %#x\n", flag); } } @@ -434,7 +454,7 @@ static void swapactive() } -static void frsync() +void frsync() { int frsyn = 0; @@ -495,17 +515,14 @@ friostat_t *fp; #if SOLARIS static void blockunknown() { - int flag; + u_32_t flag; if (opendevice(ipfname) == -1) return; - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - if (ioctl(fd, SIOCGETFF, &flag)) - perror("ioctl(SIOCGETFF)"); - + flag = get_flags(); + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) printf("log flag is currently %#x\n", flag); - } flag ^= FF_BLOCKNONIP; @@ -520,3 +537,54 @@ static void blockunknown() } } #endif + + +static void showversion() +{ + struct friostat fio; + u_32_t flags; + char *s; + + printf("ipf: %s (%d)\n", IPL_VERSION, sizeof(frentry_t)); + + if (opendevice(ipfname) != -2 && ioctl(fd, SIOCGETFS, &fio)) { + perror("ioctl(SIOCGETFS"); + return; + } + 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 ? "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 (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); +} diff --git a/sbin/ipf/ipf.h b/sbin/ipf/ipf.h index 04705ab16ec..5435972babd 100644 --- a/sbin/ipf/ipf.h +++ b/sbin/ipf/ipf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ipf.h,v 1.10 1999/07/05 20:12:43 kjell Exp $ */ +/* $OpenBSD: ipf.h,v 1.11 1999/12/15 05:20:24 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -7,7 +7,7 @@ * to the original author and the contributors. * * @(#)ipf.h 1.12 6/5/96 - * $Id: ipf.h,v 1.10 1999/07/05 20:12:43 kjell Exp $ + * $Id: ipf.h,v 1.11 1999/12/15 05:20:24 kjell Exp $ */ #ifndef __IPF_H__ @@ -16,26 +16,28 @@ #ifndef SOLARIS #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) #endif -#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 0x00020 -#define OPT_VERBOSE 0x00040 -#define OPT_DONOTHING 0x00080 -#define OPT_HITS 0x00100 -#define OPT_BRIEF 0x00200 +#define OPT_REMOVE 0x000001 +#define OPT_DEBUG 0x000002 +#define OPT_OUTQUE FR_OUTQUE /* 0x00004 */ +#define OPT_INQUE FR_INQUE /* 0x00008 */ +#define OPT_LOG FR_LOG /* 0x00010 */ +#define OPT_SHOWLIST 0x000020 +#define OPT_VERBOSE 0x000040 +#define OPT_DONOTHING 0x000080 +#define OPT_HITS 0x000100 +#define OPT_BRIEF 0x000200 #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 -#define OPT_SAVEOUT 0x20000 -#define OPT_AUTHSTATS 0x40000 -#define OPT_RAW 0x80000 +#define OPT_SHOWLINENO 0x004000 +#define OPT_PRINTFR 0x008000 +#define OPT_ZERORULEST 0x010000 +#define OPT_SAVEOUT 0x020000 +#define OPT_AUTHSTATS 0x040000 +#define OPT_RAW 0x080000 +#define OPT_NAT 0x100000 +#define OPT_GROUPS 0x200000 #ifndef __P # ifdef __STDC__ @@ -49,11 +51,11 @@ extern char *strdup __P((char *)); #endif -extern struct frentry *parse __P((char *)); +extern struct frentry *parse __P((char *, int)); extern void printfr __P((struct frentry *)); extern void binprint __P((struct frentry *)), initparse __P((void)); -extern int portnum __P((char *, u_short *)); +extern int portnum __P((char *, u_short *, int)); struct ipopt_names { @@ -65,8 +67,8 @@ struct ipopt_names { extern u_32_t buildopts __P((char *, char *, int)); -extern u_32_t hostnum __P((char *, int *)); -extern u_32_t optname __P((char ***, u_short *)); +extern u_32_t hostnum __P((char *, int *, int)); +extern u_32_t optname __P((char ***, u_short *, int)); extern void printpacket __P((ip_t *)); #if SOLARIS extern int inet_aton __P((const char *, struct in_addr *)); @@ -74,11 +76,11 @@ extern int gethostname __P((char *, int )); extern void sync __P((void)); #endif -#ifdef sun -#define STRERROR(x) sys_errlist[x] +#if defined(sun) && !SOLARIS +# define STRERROR(x) sys_errlist[x] extern char *sys_errlist[]; #else -#define STRERROR(x) strerror(x) +# define STRERROR(x) strerror(x) #endif #ifndef MIN diff --git a/sbin/ipf/opt.c b/sbin/ipf/opt.c index c659bdedda9..74df2df5c45 100644 --- a/sbin/ipf/opt.c +++ b/sbin/ipf/opt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: opt.c,v 1.10 1999/02/05 05:58:42 deraadt Exp $ */ +/* $OpenBSD: opt.c,v 1.11 1999/12/15 05:20:24 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -21,18 +21,14 @@ #include <netinet/tcp.h> #include <net/if.h> #include <arpa/inet.h> -#if defined(__OpenBSD__) -# include <netinet/ip_fil_compat.h> -#else -# include <netinet/ip_compat.h> -#endif +#include <netinet/ip_fil_compat.h> #include <netinet/tcpip.h> #include <netinet/ip_fil.h> #include "ipf.h" #if !defined(lint) static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: opt.c,v 1.10 1999/02/05 05:58:42 deraadt Exp $"; +static const char rcsid[] = "@(#)$Id: opt.c,v 1.11 1999/12/15 05:20:24 kjell Exp $"; #endif extern int opts; diff --git a/sbin/ipf/parse.c b/sbin/ipf/parse.c index 79372c41d3f..93053d32032 100644 --- a/sbin/ipf/parse.c +++ b/sbin/ipf/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.26 1999/07/06 04:38:11 deraadt Exp $ */ +/* $OpenBSD: parse.c,v 1.27 1999/12/15 05:20:24 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -6,8 +6,6 @@ * provided that this notice is preserved and due credit is given * to the original author and the contributors. */ -#include <stdio.h> -#include <string.h> #include <sys/types.h> #if !defined(__SVR4) && !defined(__svr4__) #include <strings.h> @@ -16,48 +14,56 @@ #endif #include <sys/param.h> #include <sys/time.h> -#include <stdlib.h> -#include <unistd.h> -#include <stddef.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <net/if.h> +#if __FreeBSD_version >= 300000 +# include <net/if_var.h> +#endif +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> #include <netdb.h> #include <arpa/nameser.h> #include <arpa/inet.h> #include <resolv.h> #include <ctype.h> +#include <syslog.h> #include <netinet/ip_fil_compat.h> #include <netinet/ip_fil.h> #include "ipf.h" +#include "facpri.h" #if !defined(lint) -static const char sccsid[] ="@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: parse.c,v 1.26 1999/07/06 04:38:11 deraadt Exp $"; +static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed"; +static const char rcsid[] = "@(#)$Id: parse.c,v 1.27 1999/12/15 05:20:24 kjell Exp $"; #endif extern struct ipopt_names ionames[], secclass[]; extern int opts; -int portnum __P((char *, u_short *)); -u_char tcp_flags __P((char *, u_char *)); -int addicmp __P((char ***, struct frentry *)); -int extras __P((char ***, struct frentry *)); +int portnum __P((char *, u_short *, int)); +u_char tcp_flags __P((char *, u_char *, int)); +int addicmp __P((char ***, struct frentry *, int)); +int extras __P((char ***, struct frentry *, int)); char ***seg; u_long *sa, *msk; u_short *pp, *tp; u_char *cp; int hostmask __P((char ***, u_32_t *, u_32_t *, u_short *, u_char *, - u_short *)); -int ports __P((char ***, u_short *, u_char *, u_short *)); -int icmpcode __P((char *)), addkeep __P((char ***, struct frentry *)); -int to_interface __P((frdest_t *, char *)); + u_short *, int)); +int ports __P((char ***, u_short *, u_char *, u_short *, int)); +int icmpcode __P((char *)), addkeep __P((char ***, struct frentry *, int)); +int to_interface __P((frdest_t *, char *, int)); void print_toif __P((char *, frdest_t *)); -void optprint __P((u_short, u_short, u_long, u_long)); +void optprint __P((u_short *, u_long, u_long)); int countbits __P((u_32_t)); char *portname __P((int, int)); int ratoi __P((char *, int *, int, int)); @@ -69,6 +75,7 @@ u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG }; static char thishost[MAXHOSTNAMELEN]; + void initparse() { gethostname(thishost, sizeof(thishost)); @@ -79,14 +86,15 @@ void initparse() * * parse a line read from the input filter rule file */ -struct frentry *parse(line) +struct frentry *parse(line, linenum) char *line; +int linenum; { static struct frentry fil; struct protoent *p = NULL; char *cps[31], **cpp, *endptr; u_char ch; - int i, cnt = 1; + int i, cnt = 1, j; while (*line && isspace(*line)) line++; @@ -96,6 +104,8 @@ char *line; bzero((char *)&fil, sizeof(fil)); fil.fr_mip.fi_v = 0xf; fil.fr_ip.fi_v = 4; + fil.fr_loglevel = 0xffff; + /* * break line up into max of 20 segments */ @@ -106,7 +116,7 @@ char *line; cps[i] = NULL; if (cnt < 3) { - (void)fprintf(stderr, "not enough segments in line\n"); + fprintf(stderr, "%d: not enough segments in line\n", linenum); return NULL; } @@ -117,18 +127,25 @@ char *line; if (!strcasecmp("block", *cpp)) { fil.fr_flags |= FR_BLOCK; - if (!strncasecmp(*(cpp+1), "return-icmp", 11)) { + if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19)) + fil.fr_flags |= FR_FAKEICMP; + else if (!strncasecmp(*(cpp+1), "return-icmp", 11)) fil.fr_flags |= FR_RETICMP; + if (fil.fr_flags & FR_RETICMP) { cpp++; - if (*(*cpp + 11) == '(') { - i = icmpcode(*cpp + 12); - if (i == -1) { + i = 11; + if ((strlen(*cpp) > i) && (*(*cpp + i) != '(')) + i = 19; + if (*(*cpp + i) == '(') { + i++; + j = icmpcode(*cpp + i); + if (j == -1) { fprintf(stderr, - "unrecognised icmp code %s\n", - *cpp + 12); + "%d: unrecognised icmp code %s\n", + linenum, *cpp + 20); return NULL; } - fil.fr_icode = i; + fil.fr_icode = j; } } else if (!strncasecmp(*(cpp+1), "return-rst", 10)) { fil.fr_flags |= FR_RETRST; @@ -144,10 +161,11 @@ char *line; fil.fr_flags |= FR_PREAUTH; } else if (!strcasecmp("skip", *cpp)) { cpp++; - if (ratoi(*cpp, &i, 0, INT_MAX)) + if (ratoi(*cpp, &i, 0, USHRT_MAX)) fil.fr_skip = i; else { - (void)fprintf(stderr, "integer must follow skip\n"); + fprintf(stderr, "%d: integer must follow skip\n", + linenum); return NULL; } } else if (!strcasecmp("log", *cpp)) { @@ -158,13 +176,45 @@ char *line; } if (!strcasecmp(*(cpp+1), "first")) { fil.fr_flags |= FR_LOGFIRST; + } + if (!strcasecmp(*(cpp+1), "level")) { + int fac, pri; + char *s; + + fac = 0; + pri = 0; + cpp++; + s = index(*cpp, '.'); + if (s) { + *s++ = '\0'; + fac = fac_findname(*cpp); + if (fac == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown facility", *cpp); + return NULL; + } + pri = pri_findname(s); + if (pri == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown priority", s); + return NULL; + } + } else { + pri = pri_findname(*cpp); + if (pri == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown priority", *cpp); + return NULL; + } + } + fil.fr_loglevel = fac|pri; cpp++; } } else { /* * Doesn't start with one of the action words */ - (void)fprintf(stderr, "unknown keyword (%s)\n", *cpp); + fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp); return NULL; } cpp++; @@ -174,17 +224,19 @@ char *line; else if (!strcasecmp("out", *cpp)) { fil.fr_flags |= FR_OUTQUE; if (fil.fr_flags & FR_RETICMP) { - (void)fprintf(stderr, - "Can only use return-icmp with 'in'\n"); + fprintf(stderr, + "%d: Can only use return-icmp with 'in'\n", + linenum); return NULL; } else if (fil.fr_flags & FR_RETRST) { - (void)fprintf(stderr, - "Can only use return-rst with 'in'\n"); + fprintf(stderr, + "%d: Can only use return-rst with 'in'\n", + linenum); return NULL; } } else { - (void)fprintf(stderr, - "missing 'in'/'out' keyword (%s)\n", *cpp); + fprintf(stderr, "%d: missing 'in'/'out' keyword (%s)\n", + linenum, *cpp); return NULL; } if (!*++cpp) @@ -206,8 +258,9 @@ char *line; } if (!strcasecmp(*cpp, "or-block")) { if (!(fil.fr_flags & FR_PASS)) { - (void)fprintf(stderr, - "or-block must be used with pass\n"); + fprintf(stderr, + "%d: or-block must be used with pass\n", + linenum); return NULL; } fil.fr_flags |= FR_LOGORBLOCK; @@ -223,17 +276,18 @@ char *line; *fil.fr_ifname = '\0'; if (*cpp && !strcasecmp(*cpp, "on")) { if (!*++cpp) { - (void)fprintf(stderr, "interface name missing\n"); + fprintf(stderr, "%d: interface name missing\n", + linenum); return NULL; } (void)strncpy(fil.fr_ifname, *cpp, IFNAMSIZ-1); fil.fr_ifname[IFNAMSIZ-1] = '\0'; cpp++; if (!*cpp) { - if (fil.fr_flags & FR_RETRST) { - (void)fprintf(stderr, - "%s can only be used with TCP\n", - "return-rst"); + if ((fil.fr_flags & FR_RETMASK) == FR_RETRST) { + fprintf(stderr, + "%d: %s can only be used with TCP\n", + linenum, "return-rst"); return NULL; } return &fil; @@ -242,16 +296,22 @@ char *line; if (*cpp) { if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) { cpp++; - if (to_interface(&fil.fr_dif, *cpp)) + if (to_interface(&fil.fr_dif, *cpp, linenum)) return NULL; cpp++; } if (!strcasecmp(*cpp, "to") && *(cpp + 1)) { cpp++; - if (to_interface(&fil.fr_tif, *cpp)) + if (to_interface(&fil.fr_tif, *cpp, linenum)) return NULL; cpp++; } else if (!strcasecmp(*cpp, "fastroute")) { + if (!(fil.fr_flags & FR_INQUE)) { + fprintf(stderr, + "can only use %s with 'in'\n", + "fastroute"); + return NULL; + } fil.fr_flags |= FR_FASTROUTE; cpp++; } @@ -259,7 +319,7 @@ char *line; } if (*cpp && !strcasecmp(*cpp, "tos")) { if (!*++cpp) { - (void)fprintf(stderr, "tos missing value\n"); + fprintf(stderr, "%d: tos missing value\n", linenum); return NULL; } fil.fr_tos = strtol(*cpp, NULL, 0); @@ -269,13 +329,15 @@ char *line; if (*cpp && !strcasecmp(*cpp, "ttl")) { if (!*++cpp) { - (void)fprintf(stderr, "ttl missing hopcount value\n"); + fprintf(stderr, "%d: ttl missing hopcount value\n", + linenum); return NULL; } if (ratoi(*cpp, &i, 0, 255)) fil.fr_ttl = i; else { - (void)fprintf(stderr, "invalid ttl (%s)\n", *cpp); + fprintf(stderr, "%d: invalid ttl (%s)\n", + linenum, *cpp); return NULL; } fil.fr_mip.fi_ttl = 0xff; @@ -288,44 +350,39 @@ char *line; proto = NULL; if (*cpp && !strcasecmp(*cpp, "proto")) { if (!*++cpp) { - (void)fprintf(stderr, "protocol name missing\n"); + fprintf(stderr, "%d: protocol name missing\n", linenum); return NULL; } - if (!strcasecmp(*cpp, "tcp/udp")) { + proto = *cpp++; + if (!strcasecmp(proto, "tcp/udp")) { fil.fr_ip.fi_fl |= FI_TCPUDP; fil.fr_mip.fi_fl |= FI_TCPUDP; } else { - if (!(p = getprotobyname(*cpp)) && !isdigit(**cpp)) { - (void)fprintf(stderr, - "unknown protocol (%s)\n", *cpp); + if (!(p = getprotobyname(proto)) && !isdigit(*proto)) { + fprintf(stderr, + "%d: unknown protocol (%s)\n", + linenum, proto); return NULL; } if (p) fil.fr_proto = p->p_proto; - else if (isdigit(**cpp)) { - i = (int)strtol(*cpp, &endptr, 0); + else if (isdigit(*proto)) { + i = (int)strtol(proto, &endptr, 0); if (*endptr != '\0' || i < 0 || i > 255) { - (void)fprintf(stderr, - "unknown protocol (%s)\n", *cpp); + fprintf(stderr, + "%d: unknown protocol (%s)\n", + linenum, proto); return NULL; } fil.fr_proto = i; } fil.fr_mip.fi_p = 0xff; } - proto = *cpp; - if (fil.fr_proto != IPPROTO_TCP && fil.fr_flags & FR_RETRST) { - (void)fprintf(stderr, - "%s can only be used with TCP\n", - "return-rst"); - return NULL; - } - if (!*++cpp) - return &fil; } - if (fil.fr_proto != IPPROTO_TCP && fil.fr_flags & FR_RETRST) { - (void)fprintf(stderr, "%s can only be used with TCP\n", - "return-rst"); + if ((fil.fr_proto != IPPROTO_TCP) && + ((fil.fr_flags & FR_RETMASK) == FR_RETRST)) { + fprintf(stderr, "%d: %s can only be used with TCP\n", + linenum, "return-rst"); return NULL; } @@ -334,7 +391,7 @@ char *line; */ if (!*cpp) { - fprintf(stderr, "missing source specification\n"); + fprintf(stderr, "%d: missing source specification\n", linenum); return NULL; } if (!strcasecmp(*cpp, "all")) { @@ -343,12 +400,13 @@ char *line; return &fil; } else { if (strcasecmp(*cpp, "from")) { - (void)fprintf(stderr, - "unexpected keyword (%s) - from\n", *cpp); + fprintf(stderr, "%d: unexpected keyword (%s) - from\n", + linenum, *cpp); return NULL; } if (!*++cpp) { - (void)fprintf(stderr, "missing host after from\n"); + fprintf(stderr, "%d: missing host after from\n", + linenum); return NULL; } ch = 0; @@ -358,12 +416,12 @@ char *line; } if (hostmask(&cpp, (u_32_t *)&fil.fr_src, (u_32_t *)&fil.fr_smsk, &fil.fr_sport, &ch, - &fil.fr_stop)) { + &fil.fr_stop, linenum)) { return NULL; } fil.fr_scmp = ch; if (!*cpp) { - (void)fprintf(stderr, "missing to fields\n"); + fprintf(stderr, "%d: missing to fields\n", linenum); return NULL; } @@ -371,12 +429,12 @@ char *line; * do the same for the to field (destination host) */ if (strcasecmp(*cpp, "to")) { - (void)fprintf(stderr, - "unexpected keyword (%s) - to\n", *cpp); + fprintf(stderr, "%d: unexpected keyword (%s) - to\n", + linenum, *cpp); return NULL; } if (!*++cpp) { - (void)fprintf(stderr, "missing host after to\n"); + fprintf(stderr, "%d: missing host after to\n", linenum); return NULL; } ch = 0; @@ -386,7 +444,7 @@ char *line; } if (hostmask(&cpp, (u_32_t *)&fil.fr_dst, (u_32_t *)&fil.fr_dmsk, &fil.fr_dport, &ch, - &fil.fr_dtop)) { + &fil.fr_dtop, linenum)) { return NULL; } fil.fr_dcmp = ch; @@ -398,11 +456,12 @@ char *line; */ if (fil.fr_proto && (fil.fr_dcmp || fil.fr_scmp) && fil.fr_proto != IPPROTO_TCP && fil.fr_proto != IPPROTO_UDP) { - (void)fprintf(stderr, "port operation on non tcp/udp\n"); + fprintf(stderr, "%d: port operation on non tcp/udp\n", linenum); return NULL; } if (fil.fr_icmp && fil.fr_proto != IPPROTO_ICMP) { - (void)fprintf(stderr, "icmp comparisons on wrong protocol\n"); + fprintf(stderr, "%d: icmp comparisons on wrong protocol\n", + linenum); return NULL; } @@ -411,10 +470,10 @@ char *line; if (*cpp && !strcasecmp(*cpp, "flags")) { if (!*++cpp) { - (void)fprintf(stderr, "no flags present\n"); + fprintf(stderr, "%d: no flags present\n", linenum); return NULL; } - fil.fr_tcpf = tcp_flags(*cpp, &fil.fr_tcpfm); + fil.fr_tcpf = tcp_flags(*cpp, &fil.fr_tcpfm, linenum); cpp++; } @@ -422,7 +481,7 @@ char *line; * extras... */ if (*cpp && (!strcasecmp(*cpp, "with") || !strcasecmp(*cpp, "and"))) - if (extras(&cpp, &fil)) + if (extras(&cpp, &fil, linenum)) return NULL; /* @@ -430,12 +489,12 @@ char *line; */ if (*cpp && !strcasecmp(*cpp, "icmp-type")) { if (fil.fr_proto != IPPROTO_ICMP) { - (void)fprintf(stderr, - "icmp with wrong protocol (%d)\n", - fil.fr_proto); + fprintf(stderr, + "%d: icmp with wrong protocol (%d)\n", + linenum, fil.fr_proto); return NULL; } - if (addicmp(&cpp, &fil)) + if (addicmp(&cpp, &fil, linenum)) return NULL; fil.fr_icmp = htons(fil.fr_icmp); fil.fr_icmpm = htons(fil.fr_icmpm); @@ -445,7 +504,7 @@ char *line; * Keep something... */ while (*cpp && !strcasecmp(*cpp, "keep")) - if (addkeep(&cpp, &fil)) + if (addkeep(&cpp, &fil, linenum)) return NULL; /* @@ -453,13 +512,14 @@ char *line; */ if (*cpp && !strcasecmp(*cpp, "head")) { if (!*++cpp) { - (void)fprintf(stderr, "head without group #\n"); + fprintf(stderr, "%d: head without group #\n", linenum); return NULL; } if (ratoi(*cpp, &i, 0, USHRT_MAX)) fil.fr_grhead = i; else { - (void)fprintf(stderr, "invalid group (%s)\n", *cpp); + fprintf(stderr, "%d: invalid group (%s)\n", + linenum, *cpp); return NULL; } cpp++; @@ -470,15 +530,17 @@ char *line; */ if (*cpp && !strcasecmp(*cpp, "group")) { if (!*++cpp) { - (void)fprintf(stderr, "group without group #\n"); + fprintf(stderr, "%d: group without group #\n", + linenum); return NULL; } if (ratoi(*cpp, &i, 0, USHRT_MAX)) fil.fr_group = i; else { - (void)fprintf(stderr, "invalid group (%s)\n", *cpp); - return NULL; - } + fprintf(stderr, "%d: invalid group (%s)\n", + linenum, *cpp); + return NULL; + } cpp++; } @@ -486,10 +548,10 @@ char *line; * leftovers...yuck */ if (*cpp && **cpp) { - fprintf(stderr, "unknown words at end: ["); + fprintf(stderr, "%d: unknown words at end: [", linenum); for (; *cpp; cpp++) - (void)fprintf(stderr, "%s ", *cpp); - (void)fprintf(stderr, "]\n"); + fprintf(stderr, "%s ", *cpp); + fprintf(stderr, "]\n"); return NULL; } @@ -497,7 +559,7 @@ char *line; * lazy users... */ if ((fil.fr_tcpf || fil.fr_tcpfm) && fil.fr_proto != IPPROTO_TCP) { - (void)fprintf(stderr, "TCP protocol not specified\n"); + fprintf(stderr, "%d: TCP protocol not specified\n", linenum); return NULL; } if (!(fil.fr_ip.fi_fl & FI_TCPUDP) && (fil.fr_proto != IPPROTO_TCP) && @@ -506,16 +568,18 @@ char *line; fil.fr_ip.fi_fl |= FI_TCPUDP; fil.fr_mip.fi_fl |= FI_TCPUDP; } else { - (void)fprintf(stderr, - "port comparisons for non-TCP/UDP\n"); + fprintf(stderr, + "%d: port comparisons for non-TCP/UDP\n", + linenum); return NULL; } } /* if ((fil.fr_flags & FR_KEEPFRAG) && (!(fil.fr_ip.fi_fl & FI_FRAG) || !(fil.fr_ip.fi_fl & FI_FRAG))) { - (void)fprintf(stderr, - "must use 'with frags' with 'keep frags'\n"); + fprintf(stderr, + "%d: must use 'with frags' with 'keep frags'\n", + linenum); return NULL; } */ @@ -523,9 +587,10 @@ char *line; } -int to_interface(fdp, to) +int to_interface(fdp, to, linenum) frdest_t *fdp; char *to; +int linenum; { int r = 0; char *s; @@ -534,7 +599,7 @@ char *to; fdp->fd_ifp = NULL; if (s) { *s++ = '\0'; - fdp->fd_ip.s_addr = hostnum(s, &r); + fdp->fd_ip.s_addr = hostnum(s, &r, linenum); if (r == -1) return -1; } @@ -548,10 +613,10 @@ void print_toif(tag, fdp) char *tag; frdest_t *fdp; { - (void)printf("%s %s%s", tag, fdp->fd_ifname, + printf("%s %s%s", tag, fdp->fd_ifname, (fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)"); if (fdp->fd_ip.s_addr) - (void)printf(":%s", inet_ntoa(fdp->fd_ip)); + printf(":%s", inet_ntoa(fdp->fd_ip)); putchar(' '); } @@ -561,11 +626,12 @@ frdest_t *fdp; * found in the line segments, there is an error processing this information, * or there is an error processing ports information. */ -int hostmask(seg, sa, msk, pp, cp, tp) +int hostmask(seg, sa, msk, pp, cp, tp, linenum) char ***seg; u_32_t *sa, *msk; u_short *pp, *tp; u_char *cp; +int linenum; { char *s, *endptr; int bits = -1, resolved; @@ -577,12 +643,11 @@ u_char *cp; if ((s = index(**seg, '/')) || (s = index(**seg, ':'))) { *s++ = '\0'; if (index(s, '.') || index(s, 'x')) { - /* - * Netmask possibly of the form xxx.xxx.xxx.xxx - * or 0xYYYYYYYY - */ + /* possibly of the form xxx.xxx.xxx.xxx + * or 0xYYYYYYYY */ if (inet_aton(s, &maskaddr) == 0) { - (void)fprintf(stderr, "bad mask (%s)\n", s); + fprintf(stderr, "%d: bad mask (%s)\n", + linenum, s); return -1; } *msk = maskaddr.s_addr; @@ -592,7 +657,8 @@ u_char *cp; */ bits = (int)strtol(s, &endptr, 0); if (*endptr != '\0' || bits > 32 || bits < 0) { - (void)fprintf(stderr, "bad mask (/%s)\n", s); + fprintf(stderr, "%d: bad mask (/%s)\n", + linenum, s); return -1; } if (bits == 0) @@ -600,75 +666,78 @@ u_char *cp; else *msk = htonl(0xffffffff << (32 - bits)); } - *sa = hostnum(**seg, &resolved) & *msk; + *sa = hostnum(**seg, &resolved, linenum) & *msk; if (resolved == -1) { - (void)fprintf(stderr, "bad host (%s)\n", **seg); + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); return -1; } (*seg)++; - return ports(seg, pp, cp, tp); + return ports(seg, pp, cp, tp, linenum); } /* * look for extra segments if "mask" found in right spot */ if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) { - *sa = hostnum(**seg, &resolved); + *sa = hostnum(**seg, &resolved, linenum); if (resolved == -1) { - (void)fprintf(stderr, "bad host (%s)\n", **seg); + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); return -1; } (*seg)++; (*seg)++; if (inet_aton(**seg, &maskaddr) == 0) { - (void)fprintf(stderr, "bad mask (%s)\n", **seg); + fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg); return -1; } *msk = maskaddr.s_addr; (*seg)++; *sa &= *msk; - return ports(seg, pp, cp, tp); + return ports(seg, pp, cp, tp, linenum); } if (**seg) { - *sa = hostnum(**seg, &resolved); + *sa = hostnum(**seg, &resolved, linenum); if (resolved == -1) { - (void)fprintf(stderr, "bad host (%s)\n", **seg); + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); return -1; } (*seg)++; *msk = (*sa ? inet_addr("255.255.255.255") : 0L); *sa &= *msk; - return ports(seg, pp, cp, tp); + return ports(seg, pp, cp, tp, linenum); } - (void)fprintf(stderr, "bad host (%s)\n", **seg); + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); return -1; } /* * returns an ip address as a long var as a result of either a DNS lookup or - * straight inet_addr() call + * straight inet_aton() call */ -u_32_t hostnum(host, resolved) +u_32_t hostnum(host, resolved, linenum) char *host; int *resolved; +int linenum; { struct hostent *hp; struct netent *np; - struct in_addr addr; + struct in_addr ip; *resolved = 0; if (!strcasecmp("any", host)) - return 0L; - if (inet_aton(host, &addr)) - return addr.s_addr; + return 0; + if (isdigit(*host) && inet_aton(host, &ip)) + return ip.s_addr; + if (!strcasecmp("<thishost>", host)) host = thishost; if (!(hp = gethostbyname(host))) { if (!(np = getnetbyname(host))) { *resolved = -1; - fprintf(stderr, "can't resolve hostname: %s\n", host); + fprintf(stderr, "%d: can't resolve hostname: %s\n", + linenum, host); return 0; } return htonl(np->n_net); @@ -679,10 +748,11 @@ int *resolved; /* * check for possible presence of the port fields in the line */ -int ports(seg, pp, cp, tp) +int ports(seg, pp, cp, tp, linenum) char ***seg; u_short *pp, *tp; u_char *cp; +int linenum; { int comp = -1; @@ -691,7 +761,7 @@ u_char *cp; if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) { (*seg)++; if (isdigit(***seg) && *(*seg + 2)) { - if (portnum(**seg, pp) == 0) + if (portnum(**seg, pp, linenum) == 0) return -1; (*seg)++; if (!strcmp(**seg, "<>")) @@ -699,16 +769,18 @@ u_char *cp; else if (!strcmp(**seg, "><")) comp = FR_INRANGE; else { - fprintf(stderr, "unknown range operator (%s)\n", - **seg); + fprintf(stderr, + "%d: unknown range operator (%s)\n", + linenum, **seg); return -1; } (*seg)++; if (**seg == NULL) { - fprintf(stderr, "missing 2nd port value\n"); + fprintf(stderr, "%d: missing 2nd port value\n", + linenum); return -1; } - if (portnum(**seg, tp) == 0) + if (portnum(**seg, tp, linenum) == 0) return -1; } else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq")) comp = FR_EQUAL; @@ -723,13 +795,13 @@ u_char *cp; else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge")) comp = FR_GREATERTE; else { - (void)fprintf(stderr, "unknown comparator (%s)\n", - **seg); + fprintf(stderr, "%d: unknown comparator (%s)\n", + linenum, **seg); return -1; } if (comp != FR_OUTRANGE && comp != FR_INRANGE) { (*seg)++; - if (portnum(**seg, pp) == 0) + if (portnum(**seg, pp, linenum) == 0) return -1; } *cp = comp; @@ -742,9 +814,10 @@ u_char *cp; * find the port number given by the name, either from getservbyname() or * straight atoi(). Return 1 on success, 0 on failure */ -int portnum(name, port) +int portnum(name, port, linenum) char *name; u_short *port; +int linenum; { struct servent *sp, *sp2; u_short p1 = 0; @@ -754,7 +827,7 @@ u_short *port; *port = (u_short)i; return 1; } - (void)fprintf(stderr, "unknown port \"%s\"\n", name); + fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name); return 0; } if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) { @@ -763,7 +836,7 @@ u_short *port; *port = ntohs(sp->s_port); return 1; } - (void) fprintf(stderr, "unknown service \"%s\".\n", name); + fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name); return 0; } sp = getservbyname(name, "tcp"); @@ -771,14 +844,14 @@ u_short *port; p1 = sp->s_port; sp2 = getservbyname(name, "udp"); if (!sp || !sp2) { - (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n", - name); + fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n", + linenum, name); return 0; } if (p1 != sp2->s_port) { - (void) fprintf(stderr, "%s %d/tcp is a different port to ", - name, p1); - (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port); + fprintf(stderr, "%d: %s %d/tcp is a different port to ", + linenum, name, p1); + fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port); return 0; } *port = ntohs(p1); @@ -786,9 +859,10 @@ u_short *port; } -u_char tcp_flags(flgs, mask) +u_char tcp_flags(flgs, mask, linenum) char *flgs; u_char *mask; +int linenum; { u_char tcpf = 0, tcpfm = 0, *fp = &tcpf; char *s, *t; @@ -799,7 +873,7 @@ u_char *mask; continue; } if (!(t = index(flagset, *s))) { - (void)fprintf(stderr, "unknown flag (%c)\n", *s); + fprintf(stderr, "%d: unknown flag (%c)\n", linenum, *s); return 0; } *fp |= flags[t - flagset]; @@ -814,9 +888,10 @@ u_char *mask; /* * deal with extra bits on end of the line */ -int extras(cp, fr) +int extras(cp, fr, linenum) char ***cp; struct frentry *fr; +int linenum; { u_short secmsk; u_long opts; @@ -850,18 +925,20 @@ struct frentry *fr; goto nextopt; } else if (***cp == 'o' || ***cp == 'O') { if (!*(*cp + 1)) { - (void)fprintf(stderr, - "opt missing arguements\n"); + fprintf(stderr, + "%d: opt missing arguements\n", + linenum); return -1; } (*cp)++; - if (!(opts = optname(cp, &secmsk))) + if (!(opts = optname(cp, &secmsk, linenum))) return -1; oflags = FI_OPTIONS; } else if (***cp == 's' || ***cp == 'S') { if (fr->fr_tcpf) { - (void) fprintf(stderr, - "short cannot be used with TCP flags\n"); + fprintf(stderr, + "%d: short cannot be used with TCP flags\n", + linenum); return -1; } @@ -874,13 +951,15 @@ struct frentry *fr; if (!notopt || !opts) fr->fr_mip.fi_fl |= oflags; - if (notopt) - if (!secmsk) + if (notopt) { + if (!secmsk) { fr->fr_mip.fi_optmsk |= opts; - else + } else { fr->fr_mip.fi_optmsk |= (opts & ~0x0100); - else + } + } else { fr->fr_mip.fi_optmsk |= opts; + } fr->fr_mip.fi_secmsk |= secmsk; if (notopt) { @@ -903,9 +982,10 @@ nextopt: } -u_32_t optname(cp, sp) +u_32_t optname(cp, sp, linenum) char ***cp; u_short *sp; +int linenum; { struct ipopt_names *io, *so; u_long msk = 0; @@ -920,7 +1000,8 @@ u_short *sp; break; } if (!io->on_name) { - fprintf(stderr, "unknown IP option name %s\n", s); + fprintf(stderr, "%d: unknown IP option name %s\n", + linenum, s); return 0; } if (!strcasecmp(s, "sec-class")) @@ -928,7 +1009,8 @@ u_short *sp; } if (sec && !*(*cp + 1)) { - fprintf(stderr, "missing security level after sec-class\n"); + fprintf(stderr, "%d: missing security level after sec-class\n", + linenum); return 0; } @@ -941,8 +1023,9 @@ u_short *sp; break; } if (!so->on_name) { - fprintf(stderr, "no such security level: %s\n", - s); + fprintf(stderr, + "%d: no such security level: %s\n", + linenum, s); return 0; } } @@ -954,13 +1037,14 @@ u_short *sp; #ifdef __STDC__ -void optprint(u_short secmsk, u_short secbits, u_long optmsk, u_long optbits) +void optprint(u_short *sec, u_long optmsk, u_long optbits) #else -void optprint(secmsk, secbits, optmsk, optbits) -u_short secmsk, secbits; +void optprint(sec, optmsk, optbits) +u_short *sec; u_long optmsk, optbits; #endif { + u_short secmsk = sec[0], secbits = sec[1]; struct ipopt_names *io, *so; char *s; int secflag = 0; @@ -1036,9 +1120,10 @@ char *icmptypes[] = { /* * set the icmp field to the correct type if "icmp" word is found */ -int addicmp(cp, fp) +int addicmp(cp, fp, linenum) char ***cp; struct frentry *fp; +int linenum; { char **t; int i; @@ -1050,8 +1135,9 @@ struct frentry *fp; fp->fr_proto = IPPROTO_ICMP; if (isdigit(***cp)) { if (!ratoi(**cp, &i, 0, 255)) { - (void)fprintf(stderr, - "Invalid icmp-type (%s) specified\n", **cp); + fprintf(stderr, + "%d: Invalid icmp-type (%s) specified\n", + linenum, **cp); return -1; } } else { @@ -1066,8 +1152,9 @@ struct frentry *fp; break; } if (i == -1) { - (void)fprintf(stderr, - "Invalid icmp-type (%s) specified\n", **cp); + fprintf(stderr, + "%d: Invalid icmp-type (%s) specified\n", + linenum, **cp); return -1; } } @@ -1082,8 +1169,9 @@ struct frentry *fp; (*cp)++; if (isdigit(***cp)) { if (!ratoi(**cp, &i, 0, 255)) { - (void)fprintf(stderr, - "Invalid icmp code (%s) specified\n", **cp); + fprintf(stderr, + "%d: Invalid icmp code (%s) specified\n", + linenum, **cp); return -1; } fp->fr_icmp |= (u_short)i; @@ -1091,7 +1179,8 @@ struct frentry *fp; (*cp)++; return 0; } - (void)fprintf(stderr, "Invalid icmp code (%s) specified\n", **cp); + fprintf(stderr, "%d: Invalid icmp code (%s) specified\n", + linenum, **cp); return -1; } @@ -1132,20 +1221,22 @@ char *str; /* * set the icmp field to the correct type if "icmp" word is found */ -int addkeep(cp, fp) +int addkeep(cp, fp, linenum) char ***cp; struct frentry *fp; +int linenum; { if (fp->fr_proto != IPPROTO_TCP && fp->fr_proto != IPPROTO_UDP && fp->fr_proto != IPPROTO_ICMP && !(fp->fr_ip.fi_fl & FI_TCPUDP)) { - (void)fprintf(stderr, "Can only use keep with UDP/ICMP/TCP\n"); + fprintf(stderr, "%d: Can only use keep with UDP/ICMP/TCP\n", + linenum); return -1; } (*cp)++; if (**cp && strcasecmp(**cp, "state") && strcasecmp(**cp, "frags")) { - (void)fprintf(stderr, "Unrecognised state keyword \"%s\"\n", - **cp); + fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n", + linenum, **cp); return -1; } @@ -1195,17 +1286,17 @@ int pr, port; struct servent *sv = NULL, *sv1 = NULL; if (pr == -1) { - if ((sv = getservbyport(port, "tcp"))) { + if ((sv = getservbyport(htons(port), "tcp"))) { strncpy(buf, sv->s_name, sizeof(buf)-1); buf[sizeof(buf)-1] = '\0'; - sv1 = getservbyport(port, "udp"); + sv1 = getservbyport(htons(port), "udp"); sv = strncasecmp(buf, sv->s_name, strlen(buf)) ? NULL : sv1; } if (sv) return buf; } else if (pr && (p = getprotobynumber(pr))) { - if ((sv = getservbyport(port, p->p_name))) { + if ((sv = getservbyport(htons(port), p->p_name))) { strncpy(buf, sv->s_name, sizeof(buf)-1); buf[sizeof(buf)-1] = '\0'; return buf; @@ -1227,143 +1318,164 @@ struct frentry *fp; "<>", "><"}; struct protoent *p; int ones = 0, pr; - char *s; + char *s, *u; u_char *t; + u_short sec[2]; if (fp->fr_flags & FR_PASS) - (void)printf("pass"); + printf("pass"); else if (fp->fr_flags & FR_BLOCK) { - (void)printf("block"); + printf("block"); if (fp->fr_flags & FR_RETICMP) { - (void)printf(" return-icmp"); - if (fp->fr_icode) + if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) + printf(" return-icmp-as-dest"); + else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) + printf(" return-icmp"); + if (fp->fr_icode) { if (fp->fr_icode <= MAX_ICMPCODE) printf("(%s)", icmpcodes[(int)fp->fr_icode]); else printf("(%d)", fp->fr_icode); - } - if (fp->fr_flags & FR_RETRST) - (void)printf(" return-rst"); + } + } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) + printf(" return-rst"); } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { - (void)printf("log"); + printf("log"); if (fp->fr_flags & FR_LOGBODY) - (void)printf(" body"); + printf(" body"); if (fp->fr_flags & FR_LOGFIRST) - (void)printf(" first"); + printf(" first"); } else if (fp->fr_flags & FR_ACCOUNT) - (void)printf("count"); + printf("count"); else if (fp->fr_flags & FR_AUTH) - (void)printf("auth"); + printf("auth"); else if (fp->fr_flags & FR_PREAUTH) - (void)printf("preauth"); + printf("preauth"); else if (fp->fr_skip) - (void)printf("skip %d", fp->fr_skip); + printf("skip %hu", fp->fr_skip); if (fp->fr_flags & FR_OUTQUE) - (void)printf(" out "); + printf(" out "); else - (void)printf(" in "); + printf(" in "); if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { - (void)printf("log "); + printf("log "); if (fp->fr_flags & FR_LOGBODY) - (void)printf("body "); + printf("body "); if (fp->fr_flags & FR_LOGFIRST) - (void)printf("first "); + printf("first "); if (fp->fr_flags & FR_LOGORBLOCK) - (void)printf("or-block "); + printf("or-block "); + if (fp->fr_loglevel != 0xffff) { + if (fp->fr_loglevel & LOG_FACMASK) { + s = fac_toname(fp->fr_loglevel); + if (s == NULL) + s = "!!!"; + } else + s = ""; + u = pri_toname(fp->fr_loglevel); + if (u == NULL) + u = "!!!"; + if (*s) + printf("%s.%s ", s, u); + else + printf("%s ", u); + } + } if (fp->fr_flags & FR_QUICK) - (void)printf("quick "); + printf("quick "); if (*fp->fr_ifname) { - (void)printf("on %s%s ", fp->fr_ifname, + printf("on %s%s ", fp->fr_ifname, (fp->fr_ifa || (long)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 "); + printf("fastroute "); } if (fp->fr_mip.fi_tos) - (void)printf("tos %#x ", fp->fr_tos); + printf("tos %#x ", fp->fr_tos); if (fp->fr_mip.fi_ttl) - (void)printf("ttl %d ", fp->fr_ttl); + printf("ttl %d ", fp->fr_ttl); if (fp->fr_ip.fi_fl & FI_TCPUDP) { - (void)printf("proto tcp/udp "); + printf("proto tcp/udp "); pr = -1; } else if ((pr = fp->fr_mip.fi_p)) { if ((p = getprotobynumber(fp->fr_proto))) - (void)printf("proto %s ", p->p_name); + printf("proto %s ", p->p_name); else - (void)printf("proto %d ", fp->fr_proto); + printf("proto %d ", fp->fr_proto); } printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); - if (!fp->fr_src.s_addr & !fp->fr_smsk.s_addr) - (void)printf("any "); + if (!fp->fr_src.s_addr && !fp->fr_smsk.s_addr) + printf("any "); else { - (void)printf("%s", inet_ntoa(fp->fr_src)); + printf("%s", inet_ntoa(fp->fr_src)); if ((ones = countbits(fp->fr_smsk.s_addr)) == -1) - (void)printf("/%s ", inet_ntoa(fp->fr_smsk)); + printf("/%s ", inet_ntoa(fp->fr_smsk)); else - (void)printf("/%d ", ones); + printf("/%d ", ones); } - if (fp->fr_scmp) + if (fp->fr_scmp) { if (fp->fr_scmp == FR_INRANGE || fp->fr_scmp == FR_OUTRANGE) - (void)printf("port %d %s %d ", fp->fr_sport, + printf("port %d %s %d ", fp->fr_sport, pcmp1[fp->fr_scmp], fp->fr_stop); else - (void)printf("port %s %s ", pcmp1[fp->fr_scmp], + printf("port %s %s ", pcmp1[fp->fr_scmp], portname(pr, fp->fr_sport)); + } printf("to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); - if (!fp->fr_dst.s_addr & !fp->fr_dmsk.s_addr) - (void)printf("any"); + if (!fp->fr_dst.s_addr && !fp->fr_dmsk.s_addr) + printf("any"); else { - (void)printf("%s", inet_ntoa(fp->fr_dst)); + printf("%s", inet_ntoa(fp->fr_dst)); if ((ones = countbits(fp->fr_dmsk.s_addr)) == -1) - (void)printf("/%s", inet_ntoa(fp->fr_dmsk)); + printf("/%s", inet_ntoa(fp->fr_dmsk)); else - (void)printf("/%d", ones); + 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, + 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], + 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"); + 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, - fp->fr_ip.fi_secmsk, - fp->fr_mip.fi_optmsk, - fp->fr_ip.fi_optmsk); - else if (fp->fr_mip.fi_fl & FI_OPTIONS) { + fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk) { + sec[0] = fp->fr_mip.fi_secmsk; + sec[1] = fp->fr_ip.fi_secmsk; + optprint(sec, + fp->fr_mip.fi_optmsk, 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"); + printf(" not"); + printf(" ipopt"); } if (fp->fr_mip.fi_fl & FI_SHORT) { if (!(fp->fr_ip.fi_fl & FI_SHORT)) - (void)printf(" not"); - (void)printf(" short"); + printf(" not"); + printf(" short"); } if (fp->fr_mip.fi_fl & FI_FRAG) { if (!(fp->fr_ip.fi_fl & FI_FRAG)) - (void)printf(" not"); - (void)printf(" frag"); + printf(" not"); + printf(" frag"); } } if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) { @@ -1374,14 +1486,14 @@ struct frentry *fp; type /= 256; if (type < (sizeof(icmptypes) / sizeof(char *)) && icmptypes[type]) - (void)printf(" icmp-type %s", icmptypes[type]); + printf(" icmp-type %s", icmptypes[type]); else - (void)printf(" icmp-type %d", type); + printf(" icmp-type %d", type); if (code) - (void)printf(" code %d", code); + printf(" code %d", code); } if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) { - (void)printf(" flags "); + printf(" flags "); for (s = flagset, t = flags; *s; s++, t++) if (fp->fr_tcpf & *t) (void)putchar(*s); @@ -1412,9 +1524,9 @@ struct frentry *fp; for (s = (u_char *)fp; i; i--, s++) { j++; - (void)printf("%02x ", *s); + printf("%02x ", *s); if (j == 16) { - (void)printf("\n"); + printf("\n"); j = 0; } } diff --git a/sbin/ipfstat/Makefile b/sbin/ipfstat/Makefile index 3577bfaa03c..c8373343d9f 100644 --- a/sbin/ipfstat/Makefile +++ b/sbin/ipfstat/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.4 1998/09/15 09:58:33 pattonme Exp $ +# $OpenBSD: Makefile,v 1.5 1999/12/15 05:20:25 kjell Exp $ PROG= ipfstat MAN= ipfstat.8 -SRCS= fils.c parse.c opt.c kmem.c +SRCS= fils.c parse.c opt.c kmem.c facpri.c .PATH: ${.CURDIR}/../../sbin/ipf CFLAGS+=-I${.CURDIR}/../../sbin/ipf diff --git a/sbin/ipfstat/fils.c b/sbin/ipfstat/fils.c index 9520ea00d07..5def479df1f 100644 --- a/sbin/ipfstat/fils.c +++ b/sbin/ipfstat/fils.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fils.c,v 1.16 1999/07/08 00:05:21 deraadt Exp $ */ +/* $OpenBSD: fils.c,v 1.17 1999/12/15 05:20:25 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -6,11 +6,13 @@ * provided that this notice is preserved and due credit is given * to the original author and the contributors. */ - +#ifdef __FreeBSD__ +# include <osreldate.h> +#endif #include <stdio.h> #include <string.h> #if !defined(__SVR4) && !defined(__svr4__) -#include <strings.h> +# include <strings.h> #endif #include <sys/types.h> #include <sys/time.h> @@ -28,15 +30,14 @@ #include <netinet/in_systm.h> #include <netinet/ip.h> #include <net/if.h> +#if __FreeBSD_version >= 300000 +# include <net/if_var.h> +#endif #include <netdb.h> #include <arpa/nameser.h> #include <resolv.h> #include <netinet/tcp.h> -#if defined(__OpenBSD__) -# include <netinet/ip_fil_compat.h> -#else -# include <netinet/ip_compat.h> -#endif +#include <netinet/ip_fil_compat.h> #include <netinet/ip_fil.h> #include "ipf.h" #include <netinet/ip_proxy.h> @@ -51,7 +52,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fils.c,v 1.16 1999/07/08 00:05:21 deraadt Exp $"; +static const char rcsid[] = "@(#)$Id: fils.c,v 1.17 1999/12/15 05:20:25 kjell Exp $"; #endif #define F_IN 0 @@ -70,17 +71,22 @@ static void showfrstates __P((int, ipfrstat_t *)); static void showlist __P((friostat_t *)); static void showipstates __P((int, ips_stat_t *)); static void showauthstates __P((int, fr_authstat_t *)); +static void showgroups __P((friostat_t *)); static void Usage __P((char *)); static void printlist __P((frentry_t *)); +static char *get_ifname __P((void *)); + static void Usage(name) char *name; { fprintf(stderr, - "usage: %s [-aAfhIinosv] [-d device] [-M core] [-N system]\n", name); + "usage: %s [-aAfhIinosv] [-d device] [-M core] [-N system]\n", + name); exit(1); } + int main(argc,argv) int argc; char *argv[]; @@ -108,6 +114,9 @@ char *argv[]; case 'f' : opts |= OPT_FRSTATES; break; + case 'g' : + opts |= OPT_GROUPS; + break; case 'h' : opts |= OPT_HITS; break; @@ -202,6 +211,8 @@ char *argv[]; showfrstates(fd, &ifrst); else if (opts & OPT_AUTHSTATS) showauthstates(fd, &frauthst); + else if (opts & OPT_GROUPS) + showgroups(&fio); else showstats(fd, &fio); } @@ -216,7 +227,7 @@ static void showstats(fd, fp) int fd; struct friostat *fp; { - int frf = 0; + u_32_t frf = 0; if (ioctl(fd, SIOCGETFF, &frf) == -1) perror("ioctl(SIOCGETFF)"); @@ -374,19 +385,19 @@ ips_stat_t *ipsp; printf("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n", ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp); printf("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, ipsp->iss_miss); - printf("\t%lu maximum\n\t%lu no memory\n", - ipsp->iss_max, ipsp->iss_nomem); + printf("\t%lu maximum\n\t%lu no memory\n\tbuckets in use\t%lu\n", + ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse); printf("\t%lu active\n\t%lu expired\n\t%lu closed\n", ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin); if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab))) return; - for (i = 0; i < IPSTATE_SIZE; i++) + for (i = 0; i < IPSTATE_SIZE; i++) { while (istab[i]) { if (kmemcpy((char *)&ips, (u_long)istab[i], sizeof(ips)) == -1) break; printf("%s -> ", inet_ntoa(ips.is_src)); - printf("%s ttl %ld pass %d pr %d state %d/%d\n", + printf("%s ttl %ld pass %#x pr %d state %d/%d\n", inet_ntoa(ips.is_dst), ips.is_age, ips.is_pass, ips.is_p, ips.is_state[0], ips.is_state[1]); @@ -398,11 +409,20 @@ ips_stat_t *ipsp; ips.is_pkts, ips.is_bytes); #endif if (ips.is_p == IPPROTO_TCP) - printf("\t%hu -> %hu %lu:%lu %hu:%hu", +#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + (__FreeBSD_version >= 220000) || defined(__OpenBSD__) + printf("\t%hu -> %hu %x:%x %hu:%hu", ntohs(ips.is_sport), ntohs(ips.is_dport), - ips.is_seq, ips.is_ack, - ips.is_swin, ips.is_dwin); + ips.is_send, ips.is_dend, + ips.is_maxswin, ips.is_maxdwin); +#else + printf("\t%hu -> %hu %lx:%lx %hu:%hu", + ntohs(ips.is_sport), + ntohs(ips.is_dport), + ips.is_send, ips.is_dend, + ips.is_maxswin, ips.is_maxdwin); +#endif else if (ips.is_p == IPPROTO_UDP) printf(" %hu -> %hu", ntohs(ips.is_sport), ntohs(ips.is_dport)); @@ -417,10 +437,20 @@ ips_stat_t *ipsp; printf("pass"); } else if (ips.is_pass & FR_BLOCK) { printf("block"); - if (ips.is_pass & FR_RETICMP) + switch (ips.is_pass & FR_RETMASK) + { + case FR_RETICMP : printf(" return-icmp"); - if (ips.is_pass & FR_RETRST) + break; + case FR_FAKEICMP : + printf(" return-icmp-as-dest"); + break; + case FR_RETRST : printf(" return-rst"); + break; + default : + break; + } } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) { printf("log"); if (ips.is_pass & FR_LOGBODY) @@ -435,7 +465,7 @@ ips_stat_t *ipsp; else printf(" in"); - if ((ips.is_pass & (FR_LOGB|FR_LOGP)) != 0) { + if ((ips.is_pass & FR_LOG) != 0) { printf(" log"); if (ips.is_pass & FR_LOGBODY) printf(" body"); @@ -453,7 +483,8 @@ ips_stat_t *ipsp; printf(" keep state"); printf("\n"); - printf("\tpkt_flags & %x = %x,\t", ips.is_flags & 0xf, + printf("\tpkt_flags & %x(%x) = %x,\t", + ips.is_flags & 0xf, ips.is_flags, ips.is_flags >> 4); printf("\tpkt_options & %x = %x\n", ips.is_optmsk, ips.is_opt); @@ -461,7 +492,12 @@ ips_stat_t *ipsp; ips.is_secmsk, ips.is_sec, ips.is_authmsk, ips.is_auth); istab[i] = ips.is_next; + printf("interfaces: in %s[%p] ", + get_ifname(ips.is_ifpin), ips.is_ifpin); + printf("out %s[%p]\n", + get_ifname(ips.is_ifpout), ips.is_ifpout); } + } } @@ -470,6 +506,7 @@ int fd; ipfrstat_t *ifsp; { struct ipfr *ipfrtab[IPFT_SIZE], ifr; + frentry_t fr; int i; printf("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n", @@ -485,10 +522,13 @@ ipfrstat_t *ifsp; sizeof(ifr)) == -1) break; printf("%s -> ", inet_ntoa(ifr.ipfr_src)); + if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule, + sizeof(fr)) == -1) + break; printf("%s %d %d %d %#02x = %#x\n", inet_ntoa(ifr.ipfr_dst), ifr.ipfr_id, ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos, - ifr.ipfr_pass); + fr.fr_flags); ipfrtab[i] = ifr.ipfr_next; } } @@ -498,6 +538,8 @@ static void showauthstates(fd, asp) int fd; fr_authstat_t *asp; { + frauthent_t *frap, fra; + #ifdef USE_QUAD_T printf("Authorisation hits: %qd\tmisses %qd\n", asp->fas_hits, asp->fas_miss); @@ -510,4 +552,98 @@ fr_authstat_t *asp; asp->fas_sendok); printf("queok %ld\nquefail %ld\nexpire %ld\n", asp->fas_queok, asp->fas_quefail, asp->fas_expire); + + frap = asp->fas_faelist; + while (frap) { + if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1) + break; + + printf("age %ld\t", fra.fae_age); + printfr(&fra.fae_fr); + frap = fra.fae_next; + } +} + + +static char *get_ifname(ptr) +void *ptr; +{ +#if SOLARIS + char *ifname; + ill_t ill; + + if (ptr == (void *)-1) + return "!"; + if (ptr == NULL) + return "-"; + + if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1) + return "X"; + ifname = malloc(ill.ill_name_length + 1); + if (kmemcpy(ifname, (u_long)ill.ill_name, + ill.ill_name_length) == -1) + return "X"; + return ifname; +#else +# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + defined(__OpenBSD__) +#else + char buf[32]; + int len; +# endif + struct ifnet netif; + + if (ptr == (void *)-1) + return "!"; + if (ptr == NULL) + return "-"; + + if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1) + return "X"; +# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + defined(__OpenBSD__) + return strdup(netif.if_xname); +# else + if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1) + return "X"; + if (netif.if_unit < 10) + len = 2; + else if (netif.if_unit < 1000) + len = 3; + else if (netif.if_unit < 10000) + len = 4; + else + len = 5; + buf[sizeof(buf) - len] = '\0'; + sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000); + return strdup(buf); +# endif +#endif +} + + +static void showgroups(fiop) +struct friostat *fiop; +{ + static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; + frgroup_t *fp, grp; + int on, off, i; + + on = fiop->f_active; + off = 1 - on; + + for (i = 0; i < 3; i++) { + printf("%s groups (active):\n", gnames[i]); + for (fp = fiop->f_groups[i][on]; fp; fp = grp.fg_next) + if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) + break; + else + printf("%hu\n", grp.fg_num); + printf("%s groups (inactive):\n", gnames[i]); + for (fp = fiop->f_groups[i][off]; fp; fp = grp.fg_next) + if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) + break; + else + printf("%hu\n", grp.fg_num); + } } diff --git a/sbin/ipfstat/kmem.c b/sbin/ipfstat/kmem.c index 7e3d6ba70dd..7d57fb57fbf 100644 --- a/sbin/ipfstat/kmem.c +++ b/sbin/ipfstat/kmem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kmem.c,v 1.11 1999/07/08 00:02:26 deraadt Exp $ */ +/* $OpenBSD: kmem.c,v 1.12 1999/12/15 05:20:25 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -21,7 +21,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; -static const char rcsid[] = "@(#)$Id: kmem.c,v 1.11 1999/07/08 00:02:26 deraadt Exp $"; +static const char rcsid[] = "@(#)$Id: kmem.c,v 1.12 1999/12/15 05:20:25 kjell Exp $"; #endif static int kmemfd = -1; @@ -70,3 +70,38 @@ register int n; } return 0; } + +int kstrncpy(buf, pos, n) +register char *buf; +long pos; +register int n; +{ + register int r; + + if (!n) + return 0; + if (kmemfd == -1) + if (openkmem(nlistf, memf) == -1) + return -1; + if (lseek(kmemfd, pos, 0) == -1) + { + perror("kmemcpy:lseek"); + return -1; + } + while (n > 0) { + r = read(kmemfd, buf, 1); + if (r <= 0) + { + perror("kmemcpy:read"); + return -1; + } + else + { + if (*buf == '\0') + break; + buf++; + n--; + } + } + return 0; +} diff --git a/sbin/ipfstat/kmem.h b/sbin/ipfstat/kmem.h index 5744e396d76..5da38aad7de 100644 --- a/sbin/ipfstat/kmem.h +++ b/sbin/ipfstat/kmem.h @@ -1,11 +1,11 @@ -/* $OpenBSD: kmem.h,v 1.8 1999/07/08 00:02:26 deraadt Exp $ */ +/* $OpenBSD: kmem.h,v 1.9 1999/12/15 05:20:25 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and due credit is given * to the original author and the contributors. - * $Id: kmem.h,v 1.8 1999/07/08 00:02:26 deraadt Exp $ + * $Id: kmem.h,v 1.9 1999/12/15 05:20:25 kjell Exp $ */ #ifndef __KMEM_H__ @@ -20,6 +20,7 @@ #endif extern int openkmem __P((char *, char *)); extern int kmemcpy __P((char *, long, int)); +extern int kstrncpy __P((char *, long, int)); #if defined(__NetBSD__) || defined(__OpenBSD) # include <paths.h> diff --git a/sbin/ipnat/Makefile b/sbin/ipnat/Makefile index 51d8ff5214f..4a1cd375700 100644 --- a/sbin/ipnat/Makefile +++ b/sbin/ipnat/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.5 1999/02/07 00:48:29 deraadt Exp $ +# $OpenBSD: Makefile,v 1.6 1999/12/15 05:20:24 kjell Exp $ PROG= ipnat MAN= ipnat.8 ipnat.4 ipnat.5 -SRCS= ipnat.c kmem.c +SRCS= ipnat.c kmem.c natparse.c .PATH: ${.CURDIR}/../ipfstat CFLAGS+=-I${.CURDIR}/../../sbin/ipfstat diff --git a/sbin/ipnat/ipnat.c b/sbin/ipnat/ipnat.c index 7e3272c0c59..3ca847b5063 100644 --- a/sbin/ipnat/ipnat.c +++ b/sbin/ipnat/ipnat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipnat.c,v 1.31 1999/07/25 19:14:43 hugh Exp $ */ +/* $OpenBSD: ipnat.c,v 1.32 1999/12/15 05:20:24 kjell Exp $ */ /* * Copyright (C) 1993-1998 by Darren Reed. * @@ -7,15 +7,6 @@ * to the original author and the contributors. * * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) - * - * Broken still: - * Displaying the nat with redirect entries is way confusing - * - * Example redirection line: - * rdr le1 0.0.0.0/0 port 79 -> 199.165.219.129 port 9901 - * - * Will redirect all incoming packets on le1 to any machine, port 79 to - * host 199.165.219.129, port 9901 */ #include <stdio.h> #include <string.h> @@ -43,20 +34,22 @@ #include <netinet/ip.h> #include <netinet/tcp.h> #include <net/if.h> +#if __FreeBSD_version >= 300000 +# include <net/if_var.h> +#endif #include <netdb.h> #include <arpa/nameser.h> #include <arpa/inet.h> #include <resolv.h> #include <ctype.h> -#if defined(__OpenBSD__) -# include <netinet/ip_fil_compat.h> -#else -# include <netinet/ip_compat.h> -#endif +#include <netinet/ip_fil_compat.h> #include <netinet/ip_fil.h> #include <netinet/ip_proxy.h> #include <netinet/ip_nat.h> #include "kmem.h" +#if defined(__OpenBSD__) +#include <err.h> +#endif #if defined(sun) && !SOLARIS2 # define STRERROR(x) sys_errlist[x] @@ -67,7 +60,7 @@ extern char *sys_errlist[]; #if !defined(lint) static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.31 1999/07/25 19:14:43 hugh Exp $"; +static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.32 1999/12/15 05:20:24 kjell Exp $"; #endif @@ -77,19 +70,23 @@ static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.31 1999/07/25 19:14:43 hugh Ex extern char *optarg; char *nlistf = NULL, *memf = NULL; +extern ipnat_t *natparse __P((char *, int)); +extern void natparsefile __P((int, char *, int)); +extern void printnat __P((ipnat_t *, int, void *)); -ipnat_t *parse __P((char *)); -u_32_t hostnum __P((char *, int *)); +#if defined(__OpenBSD__) +int if_addr __P((char *, struct in_addr *)); +#endif + +u_32_t hostnum __P((char *, int *, int)); u_32_t hostmask __P((char *)); -u_short portnum __P((char *, char *)); void dostats __P((int, int)), flushtable __P((int, int)); -void printnat __P((ipnat_t *, int, void *)); -void printaps __P((ap_session_t *, int )); -void parsefile __P((int, char *, int)); void usage __P((char *)); int countbits __P((u_32_t)); char *getnattype __P((ipnat_t *)); int main __P((int, char*[])); +void printaps __P((ap_session_t *, int)); +char *getsumd __P((u_32_t)); #define OPT_REM 1 #define OPT_NODO 2 @@ -98,24 +95,38 @@ int main __P((int, char*[])); #define OPT_VERBOSE 16 #define OPT_FLUSH 32 #define OPT_CLEAR 64 +#define OPT_HITS 128 void usage(name) char *name; { - fprintf(stderr, "%s: [-CFlnrsv] [-f filename]\n", name); + fprintf(stderr, "%s: [-CFhlnrsv] [-f filename]\n", name); exit(1); } +char *getsumd(sum) +u_32_t sum; +{ + static char sumdbuf[17]; + + if (sum & NAT_HW_CKSUM) + sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff); + else + sprintf(sumdbuf, "%#0x", sum); + return sumdbuf; +} + + int main(argc, argv) int argc; char *argv[]; { char *file = NULL; - int fd = -1, opts = 1, c; + int fd = -1, opts = 0, c; - while ((c = getopt(argc, argv, "CFf:lnrsv")) != -1) + while ((c = getopt(argc, argv, "CFf:hlnrsv")) != -1) switch (c) { case 'C' : @@ -127,6 +138,9 @@ char *argv[]; case 'F' : opts |= OPT_FLUSH; break; + case 'h' : + opts |=OPT_HITS; + break; case 'l' : opts |= OPT_LIST; break; @@ -134,7 +148,7 @@ char *argv[]; opts |= OPT_NODO; break; case 'r' : - opts &= ~OPT_REM; + opts |= OPT_REM; break; case 's' : opts |= OPT_STAT; @@ -156,7 +170,7 @@ char *argv[]; if (opts & (OPT_FLUSH|OPT_CLEAR)) flushtable(fd, opts); if (file) - parsefile(fd, file, opts); + natparsefile(fd, file, opts); if (opts & (OPT_LIST|OPT_STAT)) dostats(fd, opts); return 0; @@ -192,120 +206,13 @@ u_32_t ip; } -void printnat(np, verbose, ptr) -ipnat_t *np; -int verbose; -void *ptr; -{ - struct protoent *pr; - struct servent *sv; - int bits; - - switch (np->in_redir) - { - case NAT_REDIRECT : - printf("rdr "); - break; - case NAT_MAP : - printf("map "); - break; - case NAT_BIMAP : - printf("bimap "); - break; - default : - fprintf(stderr, "unknown value for in_redir: %#x\n", - np->in_redir); - break; - } - - if (np->in_redir == NAT_REDIRECT) { - printf("%s %s", np->in_ifname, inet_ntoa(np->in_out[0])); - bits = countbits(np->in_out[1].s_addr); - if (bits != -1) - printf("/%d ", bits); - else - printf("/%s ", inet_ntoa(np->in_out[1])); - if (np->in_pmin) - printf("port %d ", ntohs(np->in_pmin)); - printf("-> %s", inet_ntoa(np->in_in[0])); - if (np->in_pnext) - printf(" port %d", ntohs(np->in_pnext)); - if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) - printf(" tcp/udp"); - else if ((np->in_flags & IPN_TCP) == IPN_TCP) - printf(" tcp"); - else if ((np->in_flags & IPN_UDP) == IPN_UDP) - printf(" udp"); - printf("\n"); - if (verbose) - printf("\t%p %u %x %u %p %d\n", np->in_ifp, - np->in_space, np->in_flags, np->in_pnext, np, - np->in_use); - } else { - np->in_nextip.s_addr = htonl(np->in_nextip.s_addr); - printf("%s %s/", np->in_ifname, inet_ntoa(np->in_in[0])); - bits = countbits(np->in_in[1].s_addr); - if (bits != -1) - printf("%d ", bits); - else - printf("%s", inet_ntoa(np->in_in[1])); - printf(" -> %s/", inet_ntoa(np->in_out[0])); - bits = countbits(np->in_out[1].s_addr); - if (bits != -1) - printf("%d ", bits); - else - printf("%s", inet_ntoa(np->in_out[1])); - if (*np->in_plabel) { - pr = getprotobynumber(np->in_p); - printf(" proxy port"); - if (np->in_dport != 0) { - if (pr != NULL) - sv = getservbyport(np->in_dport, - pr->p_name); - else - sv = getservbyport(np->in_dport, NULL); - if (sv != NULL) - printf(" %s", sv->s_name); - else - printf(" %hu", ntohs(np->in_dport)); - } - printf(" %.*s/", (int)sizeof(np->in_plabel), - np->in_plabel); - if (pr != NULL) - fputs(pr->p_name, stdout); - else - printf("%d", np->in_p); - } else if (np->in_pmin || np->in_pmax) { - printf(" portmap"); - if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) - printf(" tcp/udp"); - else if (np->in_flags & IPN_TCP) - printf(" tcp"); - else if (np->in_flags & IPN_UDP) - printf(" udp"); - printf(" %d:%d", ntohs(np->in_pmin), - ntohs(np->in_pmax)); - } - printf("\n"); - if (verbose) { - printf("\tifp %p space %u nextip %s pnext %d", - np->in_ifp, np->in_space, - inet_ntoa(np->in_nextip), np->in_pnext); - printf(" flags %x use %u\n", - np->in_flags, np->in_use); - } - } -} - - void printaps(aps, opts) ap_session_t *aps; int opts; { ap_session_t ap; aproxy_t apr; - ap_tcp_t apt; - ap_udp_t apu; + raudio_t ra; if (kmemcpy((char *)&ap, (long)aps, sizeof(ap))) return; @@ -313,25 +220,44 @@ int opts; return; printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label, apr.apr_p, apr.apr_ref, apr.apr_flags); - printf("\t\t%d %s -> ", ap.aps_p, inet_ntoa(ap.aps_src)); - printf("%s [%#x ", inet_ntoa(ap.aps_dst), ap.aps_flags); + printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags); #ifdef USE_QUAD_T - printf("%qu %qu", ap.aps_bytes, ap.aps_pkts); + printf("%qu pkts %qu", ap.aps_bytes, ap.aps_pkts); #else - printf("%lu %lu", ap.aps_bytes, ap.aps_pkts); + printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts); #endif - printf(" %x[%d]]\n", ap.aps_data, ap.aps_psiz); + printf(" data %p psiz %d\n", ap.aps_data, ap.aps_psiz); if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { - printf("\t\t%hu -> %hu state[%d,%d], sel[%d,%d]\n", - ap.aps_sport, ap.aps_dport, + printf("\t\tstate[%u,%u], sel[%d,%d]\n", ap.aps_state[0], ap.aps_state[1], ap.aps_sel[0], ap.aps_sel[1]); +#if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \ + (__FreeBSD_version >= 300000) || defined(OpenBSD) printf("\t\tseq: off %hd/%hd min %x/%x\n", ap.aps_seqoff[0], ap.aps_seqoff[1], ap.aps_seqmin[0], ap.aps_seqmin[1]); printf("\t\tack: off %hd/%hd min %x/%x\n", ap.aps_ackoff[0], ap.aps_ackoff[1], ap.aps_ackmin[0], ap.aps_ackmin[1]); +#else + printf("\t\tseq: off %hd/%hd min %lx/%lx\n", + ap.aps_seqoff[0], ap.aps_seqoff[1], + ap.aps_seqmin[0], ap.aps_seqmin[1]); + printf("\t\tack: off %hd/%hd min %lx/%lx\n", + ap.aps_ackoff[0], ap.aps_ackoff[1], + ap.aps_ackmin[0], ap.aps_ackmin[1]); +#endif + } + + if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) { + if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra))) + return; + printf("\tReal Audio Proxy:\n"); + printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", + ra.rap_seenpna, ra.rap_version, ra.rap_eos); + printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf); + printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n", + ra.rap_plport, ra.rap_prport, ra.rap_srport); } } @@ -345,8 +271,8 @@ ipnat_t *ipnat; char *which; ipnat_t ipnatbuff; - if (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat, - sizeof(ipnatbuff))) + if (!ipnat || (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat, + sizeof(ipnatbuff)))) return "???"; switch (ipnatbuff.in_redir) @@ -354,6 +280,9 @@ ipnat_t *ipnat; case NAT_MAP : which = "MAP"; break; + case NAT_MAPBLK : + which = "MAP-BLOCK"; + break; case NAT_REDIRECT : which = "RDR"; break; @@ -400,6 +329,8 @@ int fd, opts; perror("kmemcpy"); break; } + if (opts & OPT_HITS) + printf("%d ", ipn.in_hits); printnat(&ipn, opts & OPT_VERBOSE, (void *)ns.ns_list); ns.ns_list = ipn.in_next; } @@ -413,80 +344,41 @@ int fd, opts; printf("\nList of active sessions:\n"); - for (i = 0; i < NAT_SIZE; i++) - for (np = nt[0][i]; np; np = nat.nat_hnext[0]) { - if (kmemcpy((char *)&nat, (long)np, - sizeof(nat))) - break; - - printf("%s %-15s %-5hu <- ->", - getnattype(nat.nat_ptr), - inet_ntoa(nat.nat_inip), - ntohs(nat.nat_inport)); - printf(" %-15s %-5hu", - inet_ntoa(nat.nat_outip), - ntohs(nat.nat_outport)); - printf(" [%s %hu]", inet_ntoa(nat.nat_oip), - ntohs(nat.nat_oport)); - if (opts & OPT_VERBOSE) { - printf("\n\tage %lu use %hu sumd %x", - nat.nat_age, nat.nat_use, - nat.nat_sumd); - printf(" bkt %d flags %x ", - i, nat.nat_flags); + for (np = ns.ns_instances; np; np = nat.nat_next) { + if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) + break; + + printf("%s %-15s %-5hu <- ->", getnattype(nat.nat_ptr), + inet_ntoa(nat.nat_inip), ntohs(nat.nat_inport)); + printf(" %-15s %-5hu", inet_ntoa(nat.nat_outip), + ntohs(nat.nat_outport)); + printf(" [%s %hu]", inet_ntoa(nat.nat_oip), + ntohs(nat.nat_oport)); + if (opts & OPT_VERBOSE) { + printf("\n\tage %lu use %hu sumd %s/", + nat.nat_age, nat.nat_use, + getsumd(nat.nat_sumd[0])); + printf("%s pr %u bkt %d flags %x ", + getsumd(nat.nat_sumd[1]), nat.nat_p, + i, nat.nat_flags); #ifdef USE_QUAD_T - printf("bytes %qu pkts %qu", - nat.nat_bytes, nat.nat_pkts); + printf("bytes %qu pkts %qu", + nat.nat_bytes, nat.nat_pkts); #else - printf("bytes %lu pkts %lu", - nat.nat_bytes, nat.nat_pkts); + printf("bytes %lu pkts %lu", + nat.nat_bytes, nat.nat_pkts); #endif #if SOLARIS - printf(" %lx", nat.nat_ipsumd); + printf(" %lx", nat.nat_ipsumd); #endif - } - putchar('\n'); - if (nat.nat_aps) - printaps(nat.nat_aps, opts); } - free(nt[0]); - } -} - + putchar('\n'); + if (nat.nat_aps) + printaps(nat.nat_aps, opts); + } -u_short portnum(name, proto) -char *name, *proto; -{ - struct servent *sp, *sp2; - u_short p1 = 0; - - if (isdigit(*name)) - return htons((u_short)atoi(name)); - if (!proto) - proto = "tcp/udp"; - if (strcasecmp(proto, "tcp/udp")) { - sp = getservbyname(name, proto); - if (sp) - return sp->s_port; - (void) fprintf(stderr, "unknown service \"%s\".\n", name); - return 0; - } - sp = getservbyname(name, "tcp"); - if (sp) - p1 = sp->s_port; - sp2 = getservbyname(name, "udp"); - if (!sp || !sp2) { - (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n", - name); - return 0; - } - if (p1 != sp2->s_port) { - (void) fprintf(stderr, "%s %d/tcp is a different port to ", - name, p1); - (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port); - return 0; + free(nt[0]); } - return p1; } @@ -513,7 +405,6 @@ char *msk; return mask; } - #if defined(__OpenBSD__) /* * if_addr(): @@ -581,14 +472,14 @@ if_addr_lose: } #endif - /* * returns an ip address as a long var as a result of either a DNS lookup or * straight inet_addr() call */ -u_32_t hostnum(host, resolved) +u_32_t hostnum(host, resolved, linenum) char *host; int *resolved; +int linenum; { struct hostent *hp; struct netent *np; @@ -599,8 +490,8 @@ int *resolved; *resolved = 0; if (!strcasecmp("any", host)) return 0L; - if (inet_aton(host, &addr)) - return (u_32_t)addr.s_addr; + if (isdigit(*host)) + return inet_addr(host); #if defined(__OpenBSD__) /* attempt a map from interface name to address */ @@ -610,7 +501,7 @@ int *resolved; if (!(hp = gethostbyname(host))) { if (!(np = getnetbyname(host))) { *resolved = -1; - fprintf(stderr, "can't resolve hostname: %s\n", host); + fprintf(stderr, "Line %d: can't resolve hostname: %s\n", linenum, host); return 0; } return htonl(np->n_net); @@ -619,346 +510,6 @@ int *resolved; } -ipnat_t *parse(line) -char *line; -{ - struct protoent *pr; - static ipnat_t ipn; - char *s, *t; - char *shost, *snetm, *dhost, *proto; - char *dnetm = NULL, *dport = NULL, *tport = NULL; - int resolved; - - bzero((char *)&ipn, sizeof(ipn)); - if ((s = strchr(line, '\n'))) - *s = '\0'; - if ((s = strchr(line, '#'))) - *s = '\0'; - if (!*line) - return NULL; - if (!(s = strtok(line, " \t"))) - return NULL; - if (!strcasecmp(s, "map")) - ipn.in_redir = NAT_MAP; - else if (!strcasecmp(s, "rdr")) - ipn.in_redir = NAT_REDIRECT; - else if (!strcasecmp(s, "bimap")) - ipn.in_redir = NAT_BIMAP; - else { - (void)fprintf(stderr, - "expected map/rdr/bimap, got \"%s\"\n", s); - return NULL; - } - - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (interface)\n"); - return NULL; - } - strncpy(ipn.in_ifname, s, sizeof(ipn.in_ifname) - 1); - ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0'; - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (%s)\n", - ipn.in_redir & NAT_MAP ? "source": "destination"); - return NULL; - } - shost = s; - - if (ipn.in_redir == NAT_REDIRECT) { - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (destination port)\n"); - return NULL; - } - - if (strcasecmp(s, "port")) { - fprintf(stderr, "missing fields (port)\n"); - return NULL; - } - - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (destination port)\n"); - return NULL; - } - - dport = s; - } - - - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (->)\n"); - return NULL; - } - if (!strcmp(s, "->")) { - snetm = strrchr(shost, '/'); - if (!snetm) { - fprintf(stderr, "missing fields (%s netmask)\n", - ipn.in_redir & NAT_MAP ? "source":"destination"); - return NULL; - } - } else { - if (strcasecmp(s, "netmask")) { - fprintf(stderr, "missing fields (netmask)\n"); - return NULL; - } - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (%s netmask)\n", - ipn.in_redir & NAT_MAP ? "source":"destination"); - return NULL; - } - snetm = s; - } - - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (%s)\n", - ipn.in_redir & NAT_MAP ? "target":"destination"); - return NULL; - } - dhost = s; - - if (ipn.in_redir & NAT_MAP) { - if (!(s = strtok(NULL, " \t"))) { - dnetm = strrchr(dhost, '/'); - if (!dnetm) { - fprintf(stderr, - "missing fields (dest netmask)\n"); - return NULL; - } - } - if (!s || !strcasecmp(s, "portmap") || - !strcasecmp(s, "proxy")) { - dnetm = strrchr(dhost, '/'); - if (!dnetm) { - fprintf(stderr, - "missing fields (dest netmask)\n"); - return NULL; - } - } else { - if (strcasecmp(s, "netmask")) { - fprintf(stderr, - "missing fields (dest netmask)\n"); - return NULL; - } - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, - "missing fields (dest netmask)\n"); - return NULL; - } - dnetm = s; - } - if (*dnetm == '/') - *dnetm++ = '\0'; - } else { - if (strrchr(dhost, '/') != NULL) { - fprintf(stderr, "No netmask supported in %s\n", - "destination host for redirect"); - return NULL; - } - /* If it's a in_redir, expect target port */ - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (destination port)\n"); - return NULL; - } - - if (strcasecmp(s, "port")) { - fprintf(stderr, "missing fields (port)\n"); - return NULL; - } - - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing fields (destination port)\n"); - return NULL; - } - tport = s; - } - - - if (*snetm == '/') - *snetm++ = '\0'; - - if (ipn.in_redir & NAT_MAP) { - ipn.in_inip = hostnum(shost, &resolved); - if (resolved == -1) - return NULL; - ipn.in_inmsk = hostmask(snetm); - ipn.in_outip = hostnum(dhost, &resolved); - if (resolved == -1) - return NULL; - ipn.in_outmsk = hostmask(dnetm); - } else { - ipn.in_inip = hostnum(dhost, &resolved); /* Inside is target */ - if (resolved == -1) - return NULL; - ipn.in_inmsk = hostmask("255.255.255.255"); - ipn.in_outip = hostnum(shost, &resolved); - if (resolved == -1) - return NULL; - ipn.in_outmsk = hostmask(snetm); - if (!(s = strtok(NULL, " \t"))) { - ipn.in_flags = IPN_TCP; /* XXX- TCP only by default */ - proto = "tcp"; - } else { - if (!strcasecmp(s, "tcp")) - ipn.in_flags = IPN_TCP; - else if (!strcasecmp(s, "udp")) - ipn.in_flags = IPN_UDP; - else if (!strcasecmp(s, "tcp/udp")) - ipn.in_flags = IPN_TCPUDP; - else if (!strcasecmp(s, "tcpudp")) - ipn.in_flags = IPN_TCPUDP; - else { - fprintf(stderr, - "expected protocol - got \"%s\"\n", s); - return NULL; - } - proto = s; - if ((s = strtok(NULL, " \t"))) { - fprintf(stderr, - "extra junk at the end of rdr: %s\n", - s); - return NULL; - } - } - ipn.in_pmin = portnum(dport, proto); /* dest port */ - ipn.in_pmax = ipn.in_pmin; /* NECESSARY of removing nats */ - ipn.in_pnext = portnum(tport, proto); /* target port */ - s = NULL; /* That's all she wrote! */ - } - ipn.in_inip &= ipn.in_inmsk; - ipn.in_outip &= ipn.in_outmsk; - - if (!s) - return &ipn; - - if (ipn.in_redir == NAT_BIMAP) { - fprintf(stderr, "extra words at the end of bimap line: %s\n", - s); - return NULL; - } - if (!strcasecmp(s, "proxy")) { - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "missing parameter for \"proxy\"\n"); - return NULL; - } - dport = NULL; - - if (!strcasecmp(s, "port")) { - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, - "missing parameter for \"port\"\n"); - return NULL; - } - - dport = s; - - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, - "missing parameter for \"proxy\"\n"); - return NULL; - } - } else { - fprintf(stderr, "missing keyword \"port\"\n"); - return NULL; - } - if ((proto = index(s, '/'))) { - *proto++ = '\0'; - if ((pr = getprotobyname(proto))) - ipn.in_p = pr->p_proto; - else - ipn.in_p = atoi(proto); - if (dport) - ipn.in_dport = portnum(dport, proto); - } else { - ipn.in_p = 0; - if (dport) - ipn.in_dport = portnum(dport, NULL); - } - - (void) strncpy(ipn.in_plabel, s, sizeof(ipn.in_plabel)); - if ((s = strtok(NULL, " \t"))) { - fprintf(stderr, "too many parameters for \"proxy\"\n"); - return NULL; - } - return &ipn; - - } - if (strcasecmp(s, "portmap")) { - fprintf(stderr, "expected \"portmap\" - got \"%s\"\n", s); - return NULL; - } - if (!(s = strtok(NULL, " \t"))) - return NULL; - if (!strcasecmp(s, "tcp")) - ipn.in_flags = IPN_TCP; - else if (!strcasecmp(s, "udp")) - ipn.in_flags = IPN_UDP; - else if (!strcasecmp(s, "tcpudp")) - ipn.in_flags = IPN_TCPUDP; - else if (!strcasecmp(s, "tcp/udp")) - ipn.in_flags = IPN_TCPUDP; - else { - fprintf(stderr, "expected protocol name - got \"%s\"\n", s); - return NULL; - } - proto = s; - if (!(s = strtok(NULL, " \t"))) { - fprintf(stderr, "no port range found\n"); - return NULL; - } - if (!(t = strchr(s, ':'))) { - fprintf(stderr, "no port range in \"%s\"\n", s); - return NULL; - } - *t++ = '\0'; - ipn.in_pmin = portnum(s, proto); - ipn.in_pmax = portnum(t, proto); - return &ipn; -} - - -void parsefile(fd, file, opts) -int fd; -char *file; -int opts; -{ - char line[512], *s; - ipnat_t *np; - FILE *fp; - int linenum = 1; - - if (strcmp(file, "-")) { - if (!(fp = fopen(file, "r"))) { - (void) fprintf(stderr, "%s: open: %s\n", file, - STRERROR(errno)); - exit(1); - } - } else - fp = stdin; - - while (fgets(line, sizeof(line) - 1, fp)) { - line[sizeof(line) - 1] = '\0'; - if ((s = strchr(line, '\n'))) - *s = '\0'; - if (!(np = parse(line))) { - if (*line) - fprintf(stderr, "%d: syntax error in \"%s\"\n", - linenum, line); - } else { - if ((opts & OPT_VERBOSE) && np) - printnat(np, opts & OPT_VERBOSE, NULL); - if (!(opts & OPT_NODO)) { - if (opts & OPT_REM) { - if (ioctl(fd, SIOCADNAT, np) == -1) - perror("ioctl(SIOCADNAT)"); - } else if (ioctl(fd, SIOCRMNAT, np) == -1) - perror("ioctl(SIOCRMNAT)"); - } - } - linenum++; - } - if (fp != stdin) - fclose(fp); -} - - void flushtable(fd, opts) int fd, opts; { |