+/* $OpenBSD: ipf.c,v 1.10 1997/02/26 04:35:39 kstailey Exp $ */
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
#if !defined(__SVR4) && !defined(__GNUC__)
#include <strings.h>
#endif
+#if !defined(__SVR4) && defined(__GNUC__) && !defined(__OpenBSD__)
+extern char *index();
+#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/file.h>
#include <resolv.h>
#include "ipf.h"
-#ifndef lint
+#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ipf.c,v 1.9 1997/01/29 01:28:03 deraadt Exp $";
+static char rcsid[] = "$DRId: ipf.c,v 2.0.1.2 1997/02/04 14:37:46 darrenr Exp $";
#endif
#if SOLARIS
-void frsync();
+void frsync(), blockunknown();
#endif
void zerostats();
static void procfile(), flushfilter(), set_state();
static void packetlogon(), swapactive(), showstats();
+static char *getline();
int main(argc,argv)
int argc;
char *argv[];
{
- int c;
+ char c;
- while ((c = getopt(argc, argv, "AsInopvdryf:F:l:EDzZ")) != -1) {
+ while ((c = getopt(argc, argv, "AdDEf:F:Il:noprsUvyzZ")) != -1) {
switch (c)
{
case 'E' :
case 's' :
swapactive();
break;
+#if SOLARIS
+ case 'U' :
+ blockunknown();
+ break;
+#endif
case 'v' :
opts |= OPT_VERBOSE;
break;
if (!strcmp(file, "-"))
fp = stdin;
else if (!(fp = fopen(file, "r"))) {
- fprintf(stderr, "%s: fopen(%s) failed: %s", name, file,
+ fprintf(stderr, "%s: fopen(%s) failed: %s\n", name, file,
STRERROR(errno));
exit(1);
}
- while (fgets(line, sizeof(line)-1, fp)) {
+ while (getline(line, sizeof(line)-1, fp)) {
/*
* treat both CR and LF as EOL
*/
!(opts & OPT_DONOTHING)) {
if (ioctl(fd, add, fr) == -1)
perror("ioctl(SIOCZRLST)");
- else
- printf("hits %d bytes %d\n",
+ else {
+ printf("hits %ld bytes %ld ",
fr->fr_hits, fr->fr_bytes);
+ printfr(fr);
+ }
} else if ((opts & OPT_REMOVE) &&
!(opts & OPT_DONOTHING)) {
if (ioctl(fd, del, fr) == -1)
(void)fclose(fp);
}
+/*
+ * Similar to fgets(3) but can handle '\\'
+ */
+static char *getline(str, size, file)
+register char *str;
+size_t size;
+FILE *file;
+{
+ register char *p;
+
+ do {
+ for (p = str;; p+= strlen(p) - 1) {
+ if (!fgets(p, size, file))
+ return(NULL);
+ p[strlen(p) -1] = '\0';
+ if (p[strlen(p) - 1] != '\\')
+ break;
+ }
+ } while (*str == '\0' || *str == '\n');
+ return(str);
+}
+
static void packetlogon(opt)
char *opt;
{
- int err, flag;
+ int err, flag = 0;
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
if ((err = ioctl(fd, SIOCGETFF, &flag)))
printf("log flag is currently %#x\n", flag);
}
- flag = 0;
+ flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK);
if (strchr(opt, 'p')) {
flag |= FF_LOGPASS;
fp->f_st[0].fr_pkl, fp->f_st[0].fr_skip,
fp->f_st[1].fr_pkl, fp->f_st[1].fr_skip);
}
+
+
+#if SOLARIS
+void blockunknown()
+{
+ int flag;
+
+ if (opendevice() == -1)
+ return;
+
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ if (ioctl(fd, SIOCGETFF, &flag))
+ perror("ioctl(SIOCGETFF)");
+
+ printf("log flag is currently %#x\n", flag);
+ }
+
+ flag ^= FF_BLOCKNONIP;
+
+ if (opendevice() != -2 && ioctl(fd, SIOCSETFF, &flag))
+ perror("ioctl(SIOCSETFF)");
+
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ if (ioctl(fd, SIOCGETFF, &flag))
+ perror("ioctl(SIOCGETFF)");
+
+ printf("log flag is now %#x\n", flag);
+ }
+}
+#endif
+/* $OpenBSD: parse.c,v 1.9 1997/02/26 04:35:40 kstailey Exp $ */
/*
* (C)opyright 1993-1996 by Darren Reed.
*
#include "ipf.h"
#include <ctype.h>
-#ifndef lint
+#if !defined(lint) && defined(LIBC_SCCS)
static char sccsid[] ="@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed";
-static char rcsid[] = "$Id: parse.c,v 1.8 1997/01/17 07:12:18 millert Exp $";
+static char rcsid[] = "$DRId: parse.c,v 2.0.1.2 1997/02/17 13:59:44 darrenr Exp $";
#endif
extern struct ipopt_names ionames[], secclass[];
struct frentry *parse();
void binprint(), printfr();
int addicmp(), extras(), hostmask(), ports(), icmpcode(), addkeep();
+int to_interface();
+
char *proto = NULL;
char flagset[] = "FSRPAU";
u_char ch;
int i, cnt = 1;
+ while (*line && isspace(*line))
+ line++;
+ if (!*line)
+ return NULL;
+
bzero((char *)&fil, sizeof(fil));
fil.fr_mip.fi_v = 0xf;
fil.fr_ip.fi_v = 4;
cpp = cps;
if (**cpp == '@')
fil.fr_hits = atoi(*cpp++ + 1) + 1;
- /*
- * does it start with one of the two possible first words ?
- */
- if (strcasecmp("block",*cpp) && strcasecmp("pass",*cpp) &&
- strcasecmp("log",*cpp) && strcasecmp("count",*cpp)) {
- (void)fprintf(stderr, "unknown keyword (%s)\n", *cpp);
- return NULL;
- }
- if (**cpp == 'b') {
+
+ if (!strcasecmp("block", *cpp)) {
fil.fr_flags = FR_BLOCK;
if (!strncasecmp(*(cpp+1), "return-icmp", 11)) {
fil.fr_flags |= FR_RETICMP;
fil.fr_flags |= FR_RETRST;
cpp++;
}
- } else if (**cpp == 'c')
+ } else if (!strcasecmp("count", *cpp)) {
fil.fr_flags = FR_ACCOUNT;
- else if (**cpp == 'p') {
+ } else if (!strcasecmp("pass", *cpp)) {
fil.fr_flags = FR_PASS;
- } else if (**cpp == 'l') {
+ } else if (!strcasecmp("log", *cpp)) {
fil.fr_flags = FR_LOG;
if (!strcasecmp(*(cpp+1), "body")) {
fil.fr_flags |= FR_LOGBODY;
fil.fr_flags |= FR_LOGFIRST;
cpp++;
}
+ } else {
+ /*
+ * Doesn't start with one of the action words
+ */
+ (void)fprintf(stderr, "unknown keyword (%s)\n", *cpp);
+ return NULL;
}
cpp++;
if (!strcasecmp("in", *cpp))
fil.fr_flags |= FR_INQUE;
- else if (!strcasecmp("out", *cpp))
+ else if (!strcasecmp("out", *cpp)) {
fil.fr_flags |= FR_OUTQUE;
- else {
+ if (fil.fr_flags & FR_RETICMP) {
+ (void)fprintf(stderr,
+ "Can only use return-icmp with 'in'\n");
+ return NULL;
+ } else if (fil.fr_flags & FR_RETRST) {
+ (void)fprintf(stderr,
+ "Can only use return-rst with 'in'\n");
+ return NULL;
+ }
+ } else {
(void)fprintf(stderr,
"missing 'in'/'out' keyword (%s)\n", *cpp);
return NULL;
fil.fr_flags |= FR_LOGFIRST;
cpp++;
}
+ if (!strcasecmp(*cpp, "or-block")) {
+ if (!(fil.fr_flags & FR_PASS)) {
+ (void)fprintf(stderr,
+ "or-block must be used with pass\n");
+ return NULL;
+ }
+ fil.fr_flags |= FR_LOGORBLOCK;
+ cpp++;
+ }
}
if (!strcasecmp("quick", *cpp)) {
}
*fil.fr_ifname = '\0';
- if (!strcasecmp(*cpp, "on")) {
+ if (*cpp && !strcasecmp(*cpp, "on")) {
if (!*++cpp) {
(void)fprintf(stderr, "interface name missing\n");
return NULL;
}
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))
}
}
}
- if (!strcasecmp(*cpp, "tos")) {
+ if (*cpp && !strcasecmp(*cpp, "tos")) {
if (!*++cpp) {
(void)fprintf(stderr, "tos missing value\n");
return NULL;
cpp++;
}
- if (!strcasecmp(*cpp, "ttl")) {
+ if (*cpp && !strcasecmp(*cpp, "ttl")) {
if (!*++cpp) {
(void)fprintf(stderr, "ttl missing hopcount value\n");
return NULL;
* check for "proto <protoname>" only decode udp/tcp/icmp as protoname
*/
proto = NULL;
- if (!strcasecmp(*cpp, "proto")) {
+ if (*cpp && !strcasecmp(*cpp, "proto")) {
if (!*++cpp) {
(void)fprintf(stderr, "protocol name missing\n");
return NULL;
* get the from host and bit mask to use against packets
*/
+ if (!*cpp) {
+ fprintf(stderr, "missing source specification\n");
+ return NULL;
+ }
if (!strcasecmp(*cpp, "all")) {
cpp++;
if (!*cpp)
!strncasecmp(**cp, "not", 3) || !strncasecmp(**cp, "opt", 4) ||
!strncasecmp(**cp, "frag", 3) || !strncasecmp(**cp, "no", 2) ||
!strncasecmp(**cp, "short", 5))) {
- if (***cp == 'n') {
+ if (***cp == 'n' || ***cp == 'N') {
notopt = 1;
(*cp)++;
continue;
- } else if (***cp == 'i') {
+ } else if (***cp == 'i' || ***cp == 'I') {
if (!notopt)
fr->fr_ip.fi_fl |= FI_OPTIONS;
fr->fr_mip.fi_fl |= FI_OPTIONS;
goto nextopt;
- } else if (***cp == 'f') {
+ } else if (***cp == 'f' || ***cp == 'F') {
if (!notopt)
fr->fr_ip.fi_fl |= FI_FRAG;
fr->fr_mip.fi_fl |= FI_FRAG;
goto nextopt;
- } else if (***cp == 'o') {
+ } else if (***cp == 'o' || ***cp == 'O') {
if (!*(*cp + 1)) {
(void)fprintf(stderr,
"opt missing arguements\n");
if (!(opts = optname(cp, &secmsk)))
return -1;
oflags = FI_OPTIONS;
- } else if (***cp == 's') {
+ } else if (***cp == 's' || ***cp == 'S') {
if (fr->fr_tcpf) {
(void) fprintf(stderr,
"short cannot be used with TCP flags\n");
return -1;
}
- if (***cp == 's')
+ if (***cp == 's' || ***cp == 'S')
fp->fr_flags |= FR_KEEPSTATE;
- else if (***cp == 'f')
+ else if (***cp == 'f' || ***cp == 'F')
fp->fr_flags |= FR_KEEPFRAG;
(*cp)++;
return 0;
static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=",
"<>", "><"};
struct protoent *p;
- frdest_t *fdp;
int ones = 0, pr;
char *s;
u_char *t;
(void)printf("body ");
if (fp->fr_flags & FR_LOGFIRST)
(void)printf("first ");
+ if (fp->fr_flags & FR_LOGORBLOCK)
+ (void)printf("or-block ");
}
if (fp->fr_flags & FR_QUICK)
(void)printf("quick ");