aboutsummaryrefslogtreecommitdiff
path: root/contrib/ipfilter/tools
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/tools')
-rw-r--r--contrib/ipfilter/tools/BNF.ipf2
-rw-r--r--contrib/ipfilter/tools/Makefile17
-rw-r--r--contrib/ipfilter/tools/ipf.c149
-rw-r--r--contrib/ipfilter/tools/ipf_y.y1288
-rw-r--r--contrib/ipfilter/tools/ipfcomp.c140
-rw-r--r--contrib/ipfilter/tools/ipfs.c46
-rw-r--r--contrib/ipfilter/tools/ipfstat.c1073
-rw-r--r--contrib/ipfilter/tools/ipfsyncd.c671
-rw-r--r--contrib/ipfilter/tools/ipftest.c414
-rw-r--r--contrib/ipfilter/tools/ipmon.c1252
-rw-r--r--contrib/ipfilter/tools/ipmon_y.y722
-rw-r--r--contrib/ipfilter/tools/ipnat.c542
-rw-r--r--contrib/ipfilter/tools/ipnat_y.y1560
-rw-r--r--contrib/ipfilter/tools/ippool.c436
-rw-r--r--contrib/ipfilter/tools/ippool_y.y551
-rw-r--r--contrib/ipfilter/tools/ipscan_y.y5
-rw-r--r--contrib/ipfilter/tools/ipsyncm.c46
-rw-r--r--contrib/ipfilter/tools/ipsyncs.c52
-rw-r--r--contrib/ipfilter/tools/lex_var.h2
-rw-r--r--contrib/ipfilter/tools/lexer.c128
-rw-r--r--contrib/ipfilter/tools/lexer.h8
21 files changed, 6473 insertions, 2631 deletions
diff --git a/contrib/ipfilter/tools/BNF.ipf b/contrib/ipfilter/tools/BNF.ipf
index 0e8433291d1c..0740c5855af9 100644
--- a/contrib/ipfilter/tools/BNF.ipf
+++ b/contrib/ipfilter/tools/BNF.ipf
@@ -66,7 +66,7 @@ facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" |
"audit" | "logalert" | "local0" | "local1" | "local2" |
"local3" | "local4" | "local5" | "local6" | "local7" .
priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" |
- "info" | "debug" .
+ "info" | "debug" .
hexnumber = "0" "x" hexstring .
hexstring = hexdigit [ hexstring ] .
diff --git a/contrib/ipfilter/tools/Makefile b/contrib/ipfilter/tools/Makefile
index 43ec1a897b83..ce1ab0e6fc22 100644
--- a/contrib/ipfilter/tools/Makefile
+++ b/contrib/ipfilter/tools/Makefile
@@ -1,8 +1,5 @@
-#
-# Copyright (C) 1993-2001 by Darren Reed.
-#
-# See the IPFILTER.LICENCE file for details on licencing.
-#
+YACC=yacc -v
+
DEST=.
all: $(DEST)/ipf_y.c $(DEST)/ipf_y.h $(DEST)/ipf_l.c \
@@ -16,7 +13,7 @@ all: $(DEST)/ipf_y.c $(DEST)/ipf_y.h $(DEST)/ipf_l.c \
$(DEST)/ipf_y.h: $(DEST)/ipf_y.c
$(DEST)/ipf_y.c: ipf_y.y
- yacc -d ipf_y.y
+ $(YACC) -d ipf_y.y
sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.c/' \
-e 's/"ipf_y.y"/"..\/tools\/ipf_y.y"/' \
y.tab.c > $(DEST)/ipf_y.c
@@ -30,7 +27,7 @@ $(DEST)/ipf_l.c: lexer.c
$(DEST)/ipmon_y.n: $(DEST)/ipmon_y.c
$(DEST)/ipmon_y.c $(DEST)/ipmon_y.h: ipmon_y.y
- yacc -d ipmon_y.y
+ $(YACC) -d ipmon_y.y
sed -e 's/yy/ipmon_yy/g' -e 's/"ipmon_y.y"/"..\/tools\/ipmon_y.y"/' \
y.tab.c > $(DEST)/ipmon_y.c
sed -e 's/yy/ipmon_yy/g' y.tab.h > $(DEST)/ipmon_y.h
@@ -43,7 +40,7 @@ $(DEST)/ipmon_l.c: lexer.c
$(DEST)/ipscan_y.h: $(DEST)/ipscan_y.c
$(DEST)/ipscan_y.c $(DEST)/ipscan_y.h: ipscan_y.y
- yacc -d ipscan_y.y
+ $(YACC) -d ipscan_y.y
sed -e 's/yy/ipscan_yy/g' \
-e 's/"ipscan_y.y"/"..\/tools\/ipscan_y.y"/' \
y.tab.c > $(DEST)/ipscan_y.c
@@ -57,7 +54,7 @@ $(DEST)/ipscan_l.c: lexer.c
$(DEST)/ippool_y.h: $(DEST)/ippool_y.c
$(DEST)/ippool_y.c $(DEST)/ippool_y.h: ippool_y.y
- yacc -d ippool_y.y
+ $(YACC) -d ippool_y.y
sed -e 's/yy/ippool_yy/g' -e 's/"ippool_y.y"/"..\/tools\/ippool_y.y"/' \
y.tab.c > $(DEST)/ippool_y.c
sed -e 's/yy/ippool_yy/g' y.tab.h > $(DEST)/ippool_y.h
@@ -70,7 +67,7 @@ $(DEST)/ippool_l.c: lexer.c
$(DEST)/ipnat_y.h: $(DEST)/ipnat_y.c
$(DEST)/ipnat_y.c $(DEST)/ipnat_y.h: ipnat_y.y
- yacc -d ipnat_y.y
+ $(YACC) -d ipnat_y.y
sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.c/ipnat_y.c/' \
-e s/\"ipnat_y.y\"/\"..\\/tools\\/ipnat_y.y\"/ \
y.tab.c > $(DEST)/ipnat_y.c
diff --git a/contrib/ipfilter/tools/ipf.c b/contrib/ipfilter/tools/ipf.c
index fe9fec2581ec..dd601426debd 100644
--- a/contrib/ipfilter/tools/ipf.c
+++ b/contrib/ipfilter/tools/ipf.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -16,12 +16,13 @@
#endif
#include "ipf.h"
#include <fcntl.h>
+#include <ctype.h>
#include <sys/ioctl.h>
#include "netinet/ipl.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipf.c,v 1.35.2.8 2007/05/10 06:12:01 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
#if !defined(__SVR4) && defined(__GNUC__)
@@ -40,23 +41,30 @@ int main __P((int, char *[]));
int opts = 0;
int outputc = 0;
int use_inet6 = 0;
+int exitstatus = 0;
-static void procfile __P((char *, char *)), flushfilter __P((char *));
-static void set_state __P((u_int)), showstats __P((friostat_t *));
-static void packetlogon __P((char *)), swapactive __P((void));
+static void procfile __P((char *));
+static void flushfilter __P((char *, int *));
+static void set_state __P((u_int));
+static void showstats __P((friostat_t *));
+static void packetlogon __P((char *));
+static void swapactive __P((void));
static int opendevice __P((char *, int));
static void closedevice __P((void));
static char *ipfname = IPL_NAME;
static void usage __P((void));
static int showversion __P((void));
static int get_flags __P((void));
-static void ipf_interceptadd __P((int, ioctlfunc_t, void *));
+static int ipf_interceptadd __P((int, ioctlfunc_t, void *));
static int fd = -1;
static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
ioctl, ioctl, ioctl,
ioctl, ioctl };
+/* XXX The following was added to satisfy a rescue/rescue/ build
+ XXX requirement. */
+int nohdrfields;
static void usage()
{
@@ -68,25 +76,28 @@ static void usage()
int main(argc,argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
- int c;
+ int c, *filter = NULL;
if (argc < 2)
usage();
- while ((c = getopt(argc, argv, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) {
+ assigndefined(getenv("IPF_PREDEFINED"));
+
+ while ((c = getopt(argc, argv, "46Ac:dDEf:F:Il:m:noPrRsT:vVyzZ")) != -1) {
switch (c)
{
case '?' :
usage();
break;
-#ifdef USE_INET6
+ case '4' :
+ use_inet6 = -1;
+ break;
case '6' :
use_inet6 = 1;
break;
-#endif
case 'A' :
opts &= ~OPT_INACTIVE;
break;
@@ -104,10 +115,10 @@ char *argv[];
opts ^= OPT_DEBUG;
break;
case 'f' :
- procfile(argv[0], optarg);
+ procfile(optarg);
break;
case 'F' :
- flushfilter(optarg);
+ flushfilter(optarg, filter);
break;
case 'I' :
opts ^= OPT_INACTIVE;
@@ -115,8 +126,11 @@ char *argv[];
case 'l' :
packetlogon(optarg);
break;
+ case 'm' :
+ filter = parseipfexpr(optarg, NULL);
+ break;
case 'n' :
- opts ^= OPT_DONOTHING;
+ opts ^= OPT_DONOTHING|OPT_DONTOPEN;
break;
case 'o' :
break;
@@ -161,14 +175,14 @@ char *argv[];
if (fd != -1)
(void) close(fd);
- return(0);
+ return(exitstatus);
/* NOTREACHED */
}
static int opendevice(ipfdev, check)
-char *ipfdev;
-int check;
+ char *ipfdev;
+ int check;
{
if (opts & OPT_DONOTHING)
return -2;
@@ -184,7 +198,7 @@ int check;
if (fd == -1)
if ((fd = open(ipfdev, O_RDWR)) == -1)
if ((fd = open(ipfdev, O_RDONLY)) == -1)
- perror("open device");
+ ipferror(fd, "open device");
return fd;
}
@@ -202,7 +216,7 @@ static int get_flags()
if ((opendevice(ipfname, 1) != -2) &&
(ioctl(fd, SIOCGETFF, &i) == -1)) {
- perror("SIOCGETFF");
+ ipferror(fd, "SIOCGETFF");
return 0;
}
return i;
@@ -210,22 +224,24 @@ static int get_flags()
static void set_state(enable)
-u_int enable;
+ u_int enable;
{
- if (opendevice(ipfname, 0) != -2)
+ if (opendevice(ipfname, 0) != -2) {
if (ioctl(fd, SIOCFRENB, &enable) == -1) {
- if (errno == EBUSY)
+ if (errno == EBUSY) {
fprintf(stderr,
"IP FIlter: already initialized\n");
- else
- perror("SIOCFRENB");
+ } else {
+ ipferror(fd, "SIOCFRENB");
+ }
}
+ }
return;
}
-static void procfile(name, file)
-char *name, *file;
+static void procfile(file)
+ char *file;
{
(void) opendevice(ipfname, 1);
@@ -241,20 +257,22 @@ char *name, *file;
}
-static void ipf_interceptadd(fd, ioctlfunc, ptr)
-int fd;
-ioctlfunc_t ioctlfunc;
-void *ptr;
+static int ipf_interceptadd(fd, ioctlfunc, ptr)
+ int fd;
+ ioctlfunc_t ioctlfunc;
+ void *ptr;
{
if (outputc)
printc(ptr);
- ipf_addrule(fd, ioctlfunc, ptr);
+ if (ipf_addrule(fd, ioctlfunc, ptr) != 0)
+ exitstatus = 1;
+ return 0;
}
static void packetlogon(opt)
-char *opt;
+ char *opt;
{
int flag, xfd, logopt, change = 0;
@@ -293,7 +311,7 @@ char *opt;
if (change == 1) {
if (opendevice(ipfname, 1) != -2 &&
(ioctl(fd, SIOCSETFF, &flag) != 0))
- perror("ioctl(SIOCSETFF)");
+ ipferror(fd, "ioctl(SIOCSETFF)");
}
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
@@ -308,11 +326,11 @@ char *opt;
if (xfd >= 0) {
logopt = 0;
if (ioctl(xfd, SIOCGETLG, &logopt))
- perror("ioctl(SIOCGETLG)");
+ ipferror(fd, "ioctl(SIOCGETLG)");
else {
logopt = 1 - logopt;
if (ioctl(xfd, SIOCSETLG, &logopt))
- perror("ioctl(SIOCSETLG)");
+ ipferror(xfd, "ioctl(SIOCSETLG)");
}
close(xfd);
}
@@ -325,11 +343,11 @@ char *opt;
if (xfd >= 0) {
logopt = 0;
if (ioctl(xfd, SIOCGETLG, &logopt))
- perror("ioctl(SIOCGETLG)");
+ ipferror(xfd, "ioctl(SIOCGETLG)");
else {
logopt = 1 - logopt;
if (ioctl(xfd, SIOCSETLG, &logopt))
- perror("ioctl(SIOCSETLG)");
+ ipferror(xfd, "ioctl(SIOCSETLG)");
}
close(xfd);
}
@@ -337,8 +355,9 @@ char *opt;
}
-static void flushfilter(arg)
-char *arg;
+static void flushfilter(arg, filter)
+ char *arg;
+ int *filter;
{
int fl = 0, rem;
@@ -359,20 +378,33 @@ char *arg;
if (!(opts & OPT_DONOTHING)) {
if (use_inet6) {
- if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
- perror("ioctl(SIOCIPFL6)");
- exit(1);
+ fprintf(stderr,
+ "IPv6 rules are no longer seperate\n");
+ } else if (filter != NULL) {
+ ipfobj_t obj;
+
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = filter[0] * sizeof(int);
+ obj.ipfo_type = IPFOBJ_IPFEXPR;
+ obj.ipfo_ptr = filter;
+ if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) {
+ ipferror(fd, "ioctl(SIOCMATCHFLUSH)");
+ fl = -1;
+ } else {
+ fl = obj.ipfo_retval;
}
} else {
if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
- perror("ioctl(SIOCIPFFL)");
+ ipferror(fd, "ioctl(SIOCIPFFL)");
exit(1);
}
}
}
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) {
printf("remove flags %s (%d)\n", arg, rem);
- printf("removed %d entries\n", fl);
+ }
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ printf("%d state entries removed\n", fl);
}
closedevice();
return;
@@ -388,7 +420,7 @@ char *arg;
perror("open(IPL_AUTH)");
else {
if (ioctl(fd, SIOCIPFFA, &fl) == -1)
- perror("ioctl(SIOCIPFFA)");
+ ipferror(fd, "ioctl(SIOCIPFFA)");
}
closedevice();
return;
@@ -411,21 +443,23 @@ char *arg;
if (!(opts & OPT_DONOTHING)) {
if (use_inet6) {
if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
- perror("ioctl(SIOCIPFL6)");
+ ipferror(fd, "ioctl(SIOCIPFL6)");
exit(1);
}
} else {
if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
- perror("ioctl(SIOCIPFFL)");
+ ipferror(fd, "ioctl(SIOCIPFFL)");
exit(1);
}
}
}
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) {
printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "",
(rem & FR_OUTQUE) ? "O" : "", rem);
- printf("removed %d filter rules\n", fl);
+ }
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ printf("%d filter rules removed\n", fl);
}
return;
}
@@ -436,7 +470,7 @@ static void swapactive()
int in = 2;
if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
- perror("ioctl(SIOCSWAPA)");
+ ipferror(fd, "ioctl(SIOCSWAPA)");
else
printf("Set %d now inactive\n", in);
}
@@ -447,7 +481,7 @@ void ipf_frsync()
int frsyn = 0;
if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1)
- perror("SIOCFRSYN");
+ ipferror(fd, "SIOCFRSYN");
else
printf("filter sync'd\n");
}
@@ -466,7 +500,7 @@ void zerostats()
if (opendevice(ipfname, 1) != -2) {
if (ioctl(fd, SIOCFRZST, &obj) == -1) {
- perror("ioctl(SIOCFRZST)");
+ ipferror(fd, "ioctl(SIOCFRZST)");
exit(-1);
}
showstats(&fio);
@@ -479,7 +513,7 @@ void zerostats()
* read the kernel stats for packets blocked and passed
*/
static void showstats(fp)
-friostat_t *fp;
+ friostat_t *fp;
{
printf("bad packets:\t\tin %lu\tout %lu\n",
fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
@@ -495,9 +529,6 @@ friostat_t *fp;
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);
}
@@ -523,7 +554,7 @@ static int showversion()
}
if (ioctl(vfd, SIOCGETFS, &ipfo)) {
- perror("ioctl(SIOCGETFS)");
+ ipferror(vfd, "ioctl(SIOCGETFS)");
close(vfd);
return 1;
}
diff --git a/contrib/ipfilter/tools/ipf_y.y b/contrib/ipfilter/tools/ipf_y.y
index 82307dec0328..822e9a5ab0ca 100644
--- a/contrib/ipfilter/tools/ipf_y.y
+++ b/contrib/ipfilter/tools/ipf_y.y
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -28,18 +28,29 @@ extern int yydebug;
extern FILE *yyin;
extern int yylineNum;
-static void newrule __P((void));
-static void setipftype __P((void));
-static u_32_t lookuphost __P((char *));
+static int addname __P((frentry_t **, char *));
+static frentry_t *addrule __P((void));
+static frentry_t *allocfr __P((void));
+static void build_dstaddr_af __P((frentry_t *, void *));
+static void build_srcaddr_af __P((frentry_t *, void *));
static void dobpf __P((int, char *));
-static void resetaddr __P((void));
-static struct alist_s *newalist __P((struct alist_s *));
+static void doipfexpr __P((char *));
+static void do_tuneint __P((char *, int));
+static void do_tunestr __P((char *, char *));
+static void fillgroup __P((frentry_t *));
+static int lookuphost __P((char *, i6addr_t *));
static u_int makehash __P((struct alist_s *));
static int makepool __P((struct alist_s *));
-static frentry_t *addrule __P((void));
+static struct alist_s *newalist __P((struct alist_s *));
+static void newrule __P((void));
+static void resetaddr __P((void));
+static void setgroup __P((frentry_t **, char *));
+static void setgrhead __P((frentry_t **, char *));
+static void seticmphead __P((frentry_t **, char *));
+static void setifname __P((frentry_t **, int, char *));
+static void setipftype __P((void));
static void setsyslog __P((void));
static void unsetsyslog __P((void));
-static void fillgroup __P((frentry_t *));
frentry_t *fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL;
@@ -52,52 +63,54 @@ static int nrules = 0;
static int newlist = 0;
static int added = 0;
static int ipffd = -1;
-static int *yycont = 0;
-static ioctlfunc_t ipfioctl[IPL_LOGSIZE];
+static int *yycont = NULL;
+static ioctlfunc_t ipfioctls[IPL_LOGSIZE];
static addfunc_t ipfaddfunc = NULL;
-static struct wordtab ipfwords[95];
-static struct wordtab addrwords[4];
-static struct wordtab maskwords[5];
-static struct wordtab icmpcodewords[17];
-static struct wordtab icmptypewords[16];
-static struct wordtab ipv4optwords[25];
-static struct wordtab ipv4secwords[9];
-static struct wordtab ipv6optwords[9];
-static struct wordtab logwords[33];
%}
%union {
char *str;
u_32_t num;
- struct in_addr ipa;
frentry_t fr;
frtuc_t *frt;
struct alist_s *alist;
u_short port;
+ struct in_addr ip4;
struct {
u_short p1;
u_short p2;
int pc;
} pc;
- struct {
+ struct ipp_s {
+ int type;
+ int ifpos;
+ int f;
+ int v;
+ int lif;
union i6addr a;
union i6addr m;
+ char *name;
} ipp;
- union i6addr ip6;
+ struct {
+ i6addr_t adr;
+ int f;
+ } adr;
+ i6addr_t ip6;
struct {
char *if1;
char *if2;
} ifs;
+ char gname[FR_GROUPLEN];
};
%type <port> portnum
%type <num> facility priority icmpcode seclevel secname icmptype
%type <num> opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr
-%type <num> portc porteq
-%type <ipa> hostname ipv4 ipv4mask ipv4_16 ipv4_24
-%type <ip6> ipv6mask
+%type <num> portc porteq ipmask maskopts
+%type <ip4> ipv4 ipv4_16 ipv4_24
+%type <adr> hostname
%type <ipp> addr ipaddr
-%type <str> servicename name interfacename
+%type <str> servicename name interfacename groupname
%type <pc> portrange portcomp
%type <alist> addrlist poollist
%type <ifs> onname
@@ -109,30 +122,32 @@ static struct wordtab logwords[33];
%token YY_RANGE_OUT YY_RANGE_IN
%token <ip6> YY_IPV6
+%token IPFY_SET
%token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL IPFY_NOMATCH
%token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST
%token IPFY_IN IPFY_OUT
%token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA
%token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO
-%token IPFY_TOS IPFY_TTL IPFY_PROTO
+%token IPFY_TOS IPFY_TTL IPFY_PROTO IPFY_INET IPFY_INET6
%token IPFY_HEAD IPFY_GROUP
%token IPFY_AUTH IPFY_PREAUTH
-%token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK
-%token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP
+%token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK IPFY_L5AS
+%token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP IPFY_DECAPS
%token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH
-%token IPFY_PPS
+%token IPFY_IPFEXPR IPFY_PPS IPFY_FAMILY IPFY_DSTLIST
%token IPFY_ESP IPFY_AH
%token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT
%token IPFY_TCPUDP IPFY_TCP IPFY_UDP
%token IPFY_FLAGS IPFY_MULTICAST
%token IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER
-%token IPFY_PORT
-%token IPFY_NOW
+%token IPFY_RPC IPFY_PORT
+%token IPFY_NOW IPFY_COMMENT IPFY_RULETTL
%token IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE
%token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG
%token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR
%token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE
-%token IPFY_SYNC IPFY_FRAGBODY
+%token IPFY_SYNC IPFY_FRAGBODY IPFY_ICMPHEAD IPFY_NOLOG IPFY_LOOSE
+%token IPFY_MAX_SRCS IPFY_MAX_PER_SRC
%token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP
%token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR
%token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO
@@ -140,10 +155,10 @@ static struct wordtab logwords[33];
%token IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS
%token IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP
%token IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2
-%token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3
+%token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3 IPFY_DOI
-%token IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS
-%token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING
+%token IPFY_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS
+%token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING IPFY_V6HDR
%token IPFY_IPV6OPT_MOBILITY IPFY_IPV6OPT_ESP IPFY_IPV6OPT_FRAG
%token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH
@@ -168,16 +183,36 @@ static struct wordtab logwords[33];
%token IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN
%token IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG
%%
-file: line
+file: settings rules
+ | rules
+ ;
+
+settings:
+ YY_COMMENT
+ | setting
+ | settings setting
+ ;
+
+rules: line
| assign
- | file line
- | file assign
+ | rules line
+ | rules assign
+ ;
+
+setting:
+ IPFY_SET YY_STR YY_NUMBER ';' { do_tuneint($2, $3); }
+ | IPFY_SET YY_STR YY_HEX ';' { do_tuneint($2, $3); }
+ | IPFY_SET YY_STR YY_STR ';' { do_tunestr($2, $3); }
;
line: rule { while ((fr = frtop) != NULL) {
frtop = fr->fr_next;
fr->fr_next = NULL;
- (*ipfaddfunc)(ipffd, ipfioctl[IPL_LOGIPF], fr);
+ if ((fr->fr_type == FR_T_IPF) &&
+ (fr->fr_ip.fi_v == 0))
+ fr->fr_mip.fi_v = 0;
+ /* XXX validate ? */
+ (*ipfaddfunc)(ipffd, ipfioctls[IPL_LOGIPF], fr);
fr->fr_next = frold;
frold = fr;
}
@@ -231,10 +266,37 @@ markout:
rulemain:
ipfrule
| bpfrule
+ | exprrule
;
ipfrule:
- tos ttl proto ip
+ family tos ttl proto ip
+ ;
+
+family: | IPFY_FAMILY IPFY_INET { if (use_inet6 == 1) {
+ YYERROR;
+ } else {
+ frc->fr_family = AF_INET;
+ }
+ }
+ | IPFY_INET { if (use_inet6 == 1) {
+ YYERROR;
+ } else {
+ frc->fr_family = AF_INET;
+ }
+ }
+ | IPFY_FAMILY IPFY_INET6 { if (use_inet6 == -1) {
+ YYERROR;
+ } else {
+ frc->fr_family = AF_INET6;
+ }
+ }
+ | IPFY_INET6 { if (use_inet6 == -1) {
+ YYERROR;
+ } else {
+ frc->fr_family = AF_INET6;
+ }
+ }
;
bpfrule:
@@ -242,12 +304,16 @@ bpfrule:
| IPFY_BPFV6 '{' YY_STR '}' { dobpf(6, $3); free($3); }
;
+exprrule:
+ IPFY_IPFEXPR '{' YY_STR '}' { doipfexpr($3); }
+ ;
+
ruletail:
with keep head group
;
ruletail2:
- pps age new
+ pps age new rulettl comment
;
intag: settagin matchtagin
@@ -269,6 +335,7 @@ action: block
| IPFY_NOMATCH { fr->fr_flags |= FR_NOMATCH; }
| log
| IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; }
+ | decaps { fr->fr_flags |= FR_DECAPSULATE; }
| auth
| IPFY_SKIP YY_NUMBER { fr->fr_flags |= FR_SKIP;
fr->fr_arg = $2; }
@@ -291,6 +358,11 @@ blockreturn:
| IPFY_RETRST { fr->fr_flags |= FR_RETRST; }
;
+decaps: IPFY_DECAPS
+ | IPFY_DECAPS IPFY_L5AS '(' YY_STR ')'
+ { fr->fr_icode = atoi($4); }
+ ;
+
log: IPFY_LOG { fr->fr_flags |= FR_LOG; }
| IPFY_LOG logoptions { fr->fr_flags |= FR_LOG; }
;
@@ -300,10 +372,11 @@ auth: IPFY_AUTH { fr->fr_flags |= FR_AUTH; }
| IPFY_PREAUTH { fr->fr_flags |= FR_PREAUTH; }
;
-func: YY_STR '/' YY_NUMBER { fr->fr_func = nametokva($1,
- ipfioctl[IPL_LOGIPF]);
- fr->fr_arg = $3;
- free($1); }
+func: YY_STR '/' YY_NUMBER
+ { fr->fr_func = nametokva($1, ipfioctls[IPL_LOGIPF]);
+ fr->fr_arg = $3;
+ free($1);
+ }
;
inopts:
@@ -330,6 +403,7 @@ outopt:
| on
| dup
| proute
+ | froute
| replyto
;
@@ -346,7 +420,7 @@ toslist:
| YY_HEX { DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) }
| toslist lmore YY_NUMBER
{ DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
- | toslist lmore YY_HEX
+ | toslist lmore YY_HEX
{ DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) }
;
@@ -355,10 +429,10 @@ ttl: | setttl YY_NUMBER
| setttl lstart ttllist lend
;
-lstart: '(' { newlist = 1; fr = frc; added = 0; }
+lstart: '{' { newlist = 1; fr = frc; added = 0; }
;
-lend: ')' { nrules += added; }
+lend: '}' { nrules += added; }
;
lmore: lanother { if (newlist == 1) {
@@ -394,20 +468,25 @@ protox: IPFY_PROTO { setipftype();
ip: srcdst flags icmp
;
-group: | IPFY_GROUP YY_STR { DOALL(strncpy(fr->fr_group, $2, \
- FR_GROUPLEN); \
- fillgroup(fr););
- free($2); }
- | IPFY_GROUP YY_NUMBER { DOALL(sprintf(fr->fr_group, "%d", \
- $2); \
- fillgroup(fr);) }
+group: | IPFY_GROUP groupname { DOALL(setgroup(&fr, $2); \
+ fillgroup(fr););
+ free($2);
+ }
+ ;
+
+head: | IPFY_HEAD groupname { DOALL(setgrhead(&fr, $2););
+ free($2);
+ }
;
-head: | IPFY_HEAD YY_STR { DOALL(strncpy(fr->fr_grhead, $2, \
- FR_GROUPLEN););
- free($2); }
- | IPFY_HEAD YY_NUMBER { DOALL(sprintf(fr->fr_grhead, "%d", \
- $2);) }
+groupname:
+ YY_STR { $$ = $1;
+ if (strlen($$) >= FR_GROUPLEN)
+ $$[FR_GROUPLEN - 1] = '\0';
+ }
+ | YY_NUMBER { $$ = malloc(16);
+ sprintf($$, "%d", $1);
+ }
;
settagin:
@@ -461,6 +540,15 @@ pps: | IPFY_PPS YY_NUMBER { DOALL(fr->fr_pps = $2;) }
new: | savegroup file restoregroup
;
+rulettl:
+ | IPFY_RULETTL YY_NUMBER { DOALL(fr->fr_die = $2;) }
+ ;
+
+comment:
+ | IPFY_COMMENT YY_STR { DOALL(fr->fr_comment = addname(&fr, \
+ $2);) }
+ ;
+
savegroup:
'{'
;
@@ -472,76 +560,92 @@ restoregroup:
logopt: log
;
-quick:
- IPFY_QUICK { fr->fr_flags |= FR_QUICK; }
+quick: IPFY_QUICK { fr->fr_flags |= FR_QUICK; }
;
-on: IPFY_ON onname
+on: IPFY_ON onname { setifname(&fr, 0, $2.if1);
+ free($2.if1);
+ if ($2.if2 != NULL) {
+ setifname(&fr, 1,
+ $2.if2);
+ free($2.if2);
+ }
+ }
| IPFY_ON lstart onlist lend
- | IPFY_ON onname IPFY_INVIA vianame
- | IPFY_ON onname IPFY_OUTVIA vianame
+ | IPFY_ON onname IPFY_INVIA vianame { setifname(&fr, 0, $2.if1);
+ free($2.if1);
+ if ($2.if2 != NULL) {
+ setifname(&fr, 1,
+ $2.if2);
+ free($2.if2);
+ }
+ }
+ | IPFY_ON onname IPFY_OUTVIA vianame { setifname(&fr, 0, $2.if1);
+ free($2.if1);
+ if ($2.if2 != NULL) {
+ setifname(&fr, 1,
+ $2.if2);
+ free($2.if2);
+ }
+ }
;
-onlist: onname { DOREM(strncpy(fr->fr_ifnames[0], $1.if1, \
- sizeof(fr->fr_ifnames[0])); \
- if ($1.if2 != NULL) { \
- strncpy(fr->fr_ifnames[1], \
- $1.if2, \
- sizeof(fr->fr_ifnames[1]));\
- } \
- ) }
- | onlist lmore onname { DOREM(strncpy(fr->fr_ifnames[0], $3.if1, \
- sizeof(fr->fr_ifnames[0])); \
- if ($3.if2 != NULL) { \
- strncpy(fr->fr_ifnames[1], \
- $3.if2, \
- sizeof(fr->fr_ifnames[1]));\
- } \
- ) }
+onlist: onname { DOREM(setifname(&fr, 0, $1.if1); \
+ if ($1.if2 != NULL) \
+ setifname(&fr, 1, $1.if2); \
+ )
+ free($1.if1);
+ if ($1.if2 != NULL)
+ free($1.if2);
+ }
+ | onlist lmore onname { DOREM(setifname(&fr, 0, $3.if1); \
+ if ($3.if2 != NULL) \
+ setifname(&fr, 1, $3.if2); \
+ )
+ free($3.if1);
+ if ($3.if2 != NULL)
+ free($3.if2);
+ }
;
-onname: interfacename
- { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
- $$.if1 = fr->fr_ifnames[0];
- $$.if2 = NULL;
- free($1);
- }
+onname: interfacename { $$.if1 = $1;
+ $$.if2 = NULL;
+ }
| interfacename ',' interfacename
- { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0]));
- $$.if1 = fr->fr_ifnames[0];
- free($1);
- strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1]));
- $$.if1 = fr->fr_ifnames[1];
- free($3);
- }
+ { $$.if1 = $1;
+ $$.if2 = $3;
+ }
;
vianame:
- name
- { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
- free($1);
- }
- | name ',' name
- { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2]));
- free($1);
- strncpy(fr->fr_ifnames[3], $3, sizeof(fr->fr_ifnames[3]));
- free($3);
- }
+ name { setifname(&fr, 2, $1);
+ free($1);
+ }
+ | name ',' name { setifname(&fr, 2, $1);
+ free($1);
+ setifname(&fr, 3, $3);
+ free($3);
+ }
;
dup: IPFY_DUPTO name
- { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
+ { int idx = addname(&fr, $2);
+ fr->fr_dif.fd_name = idx;
free($2);
}
- | IPFY_DUPTO name duptoseparator hostname
- { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
- fr->fr_dif.fd_ip = $4;
- yyexpectaddr = 0;
- free($2);
+ | IPFY_DUPTO IPFY_DSTLIST '/' name
+ { int idx = addname(&fr, $4);
+ fr->fr_dif.fd_name = idx;
+ fr->fr_dif.fd_type = FRD_DSTLIST;
+ free($4);
}
- | IPFY_DUPTO name duptoseparator YY_IPV6
- { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname));
- bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6));
+ | IPFY_DUPTO name duptoseparator hostname
+ { int idx = addname(&fr, $2);
+ fr->fr_dif.fd_name = idx;
+ fr->fr_dif.fd_ptr = (void *)-1;
+ fr->fr_dif.fd_ip6 = $4.adr;
+ if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC)
+ fr->fr_family = $4.f;
yyexpectaddr = 0;
free($2);
}
@@ -555,18 +659,23 @@ froute: IPFY_FROUTE { fr->fr_flags |= FR_FASTROUTE; }
;
proute: routeto name
- { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
+ { int idx = addname(&fr, $2);
+ fr->fr_tif.fd_name = idx;
free($2);
}
- | routeto name duptoseparator hostname
- { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
- fr->fr_tif.fd_ip = $4;
- yyexpectaddr = 0;
- free($2);
+ | routeto IPFY_DSTLIST '/' name
+ { int idx = addname(&fr, $4);
+ fr->fr_tif.fd_name = idx;
+ fr->fr_tif.fd_type = FRD_DSTLIST;
+ free($4);
}
- | routeto name duptoseparator YY_IPV6
- { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname));
- bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6));
+ | routeto name duptoseparator hostname
+ { int idx = addname(&fr, $2);
+ fr->fr_tif.fd_name = idx;
+ fr->fr_tif.fd_ptr = (void *)-1;
+ fr->fr_tif.fd_ip6 = $4.adr;
+ if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC)
+ fr->fr_family = $4.f;
yyexpectaddr = 0;
free($2);
}
@@ -579,12 +688,22 @@ routeto:
replyto:
IPFY_REPLY_TO name
- { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
+ { int idx = addname(&fr, $2);
+ fr->fr_rif.fd_name = idx;
free($2);
}
+ | IPFY_REPLY_TO IPFY_DSTLIST '/' name
+ { fr->fr_rif.fd_name = addname(&fr, $4);
+ fr->fr_rif.fd_type = FRD_DSTLIST;
+ free($4);
+ }
| IPFY_REPLY_TO name duptoseparator hostname
- { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname));
- fr->fr_rif.fd_ip = $4;
+ { int idx = addname(&fr, $2);
+ fr->fr_rif.fd_name = idx;
+ fr->fr_rif.fd_ptr = (void *)-1;
+ fr->fr_rif.fd_ip6 = $4.adr;
+ if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC)
+ fr->fr_family = $4.f;
free($2);
}
;
@@ -614,27 +733,29 @@ srcdst: | IPFY_ALL
;
protocol:
- YY_NUMBER { DOREM(fr->fr_proto = $1; \
- fr->fr_mproto = 0xff;) }
+ YY_NUMBER { DOALL(fr->fr_proto = $1; \
+ fr->fr_mproto = 0xff;)
+ }
| YY_STR { if (!strcmp($1, "tcp-udp")) {
- DOREM(fr->fr_flx |= FI_TCPUDP; \
+ DOALL(fr->fr_flx |= FI_TCPUDP; \
fr->fr_mflx |= FI_TCPUDP;)
} else {
int p = getproto($1);
if (p == -1)
yyerror("protocol unknown");
- DOREM(fr->fr_proto = p; \
+ DOALL(fr->fr_proto = p; \
fr->fr_mproto = 0xff;)
}
free($1);
- }
+ }
| YY_STR nextstring YY_STR
{ if (!strcmp($1, "tcp") &&
!strcmp($3, "udp")) {
DOREM(fr->fr_flx |= FI_TCPUDP; \
fr->fr_mflx |= FI_TCPUDP;)
- } else
+ } else {
YYERROR;
+ }
free($1);
free($3);
}
@@ -667,7 +788,8 @@ to: IPFY_TO { if (fr == NULL)
printf("set yyexpectaddr\n");
yycont = &yyexpectaddr;
yysetdict(addrwords);
- resetaddr(); }
+ resetaddr();
+ }
;
with: | andwith withlist
@@ -678,7 +800,7 @@ andwith:
| IPFY_AND { nowith = 0; setipftype(); }
;
-flags: | startflags flagset
+flags: | startflags flagset
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) }
| startflags flagset '/' flagset
{ DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) }
@@ -717,35 +839,14 @@ srcobject:
;
srcaddr:
- addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \
- bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \
- if (dynamic != -1) { \
- fr->fr_satype = ifpflag; \
- fr->fr_ipf->fri_sifpidx = dynamic; \
- } else if (pooled || hashed) \
- fr->fr_satype = FRI_LOOKUP;)
- }
+ addr { build_srcaddr_af(fr, &$1); }
| lstart srcaddrlist lend
;
srcaddrlist:
- addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \
- bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \
- if (dynamic != -1) { \
- fr->fr_satype = ifpflag; \
- fr->fr_ipf->fri_sifpidx = dynamic; \
- } else if (pooled || hashed) \
- fr->fr_satype = FRI_LOOKUP;)
- }
+ addr { build_srcaddr_af(fr, &$1); }
| srcaddrlist lmore addr
- { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_src, sizeof($3.a)); \
- bcopy(&($3.m), &fr->fr_mip.fi_src, sizeof($3.m)); \
- if (dynamic != -1) { \
- fr->fr_satype = ifpflag; \
- fr->fr_ipf->fri_sifpidx = dynamic; \
- } else if (pooled || hashed) \
- fr->fr_satype = FRI_LOOKUP;)
- }
+ { build_srcaddr_af(fr, &$3); }
;
srcport:
@@ -770,10 +871,10 @@ fromport:
srcportlist:
portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) }
- | portnum ':' portnum
+ | portnum ':' portnum
{ DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $1; \
fr->fr_stop = $3;) }
- | portnum YY_RANGE_IN portnum
+ | portnum YY_RANGE_IN portnum
{ DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $1; \
fr->fr_stop = $3;) }
| srcportlist lmore portnum
@@ -794,34 +895,25 @@ dstobject:
;
dstaddr:
- addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \
- bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \
- if (dynamic != -1) { \
- fr->fr_datype = ifpflag; \
- fr->fr_ipf->fri_difpidx = dynamic; \
- } else if (pooled || hashed) \
- fr->fr_datype = FRI_LOOKUP;)
+ addr { if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) &&
+ ($1.f != frc->fr_family))
+ yyerror("1.src/dst address family mismatch");
+ build_dstaddr_af(fr, &$1);
}
| lstart dstaddrlist lend
;
dstaddrlist:
- addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \
- bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \
- if (dynamic != -1) { \
- fr->fr_datype = ifpflag; \
- fr->fr_ipf->fri_difpidx = dynamic; \
- } else if (pooled || hashed) \
- fr->fr_datype = FRI_LOOKUP;)
+ addr { if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) &&
+ ($1.f != frc->fr_family))
+ yyerror("2.src/dst address family mismatch");
+ build_dstaddr_af(fr, &$1);
}
| dstaddrlist lmore addr
- { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_dst, sizeof($3.a)); \
- bcopy(&($3.m), &fr->fr_mip.fi_dst, sizeof($3.m)); \
- if (dynamic != -1) { \
- fr->fr_datype = ifpflag; \
- fr->fr_ipf->fri_difpidx = dynamic; \
- } else if (pooled || hashed) \
- fr->fr_datype = FRI_LOOKUP;)
+ { if (($3.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) &&
+ ($3.f != frc->fr_family))
+ yyerror("3.src/dst address family mismatch");
+ build_dstaddr_af(fr, &$3);
}
;
@@ -848,10 +940,10 @@ toport:
dstportlist:
portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) }
- | portnum ':' portnum
+ | portnum ':' portnum
{ DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $1; \
fr->fr_dtop = $3;) }
- | portnum YY_RANGE_IN portnum
+ | portnum YY_RANGE_IN portnum
{ DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $1; \
fr->fr_dtop = $3;) }
| dstportlist lmore portnum
@@ -865,141 +957,234 @@ dstportlist:
;
addr: pool '/' YY_NUMBER { pooled = 1;
+ yyexpectaddr = 0;
+ $$.type = FRI_LOOKUP;
+ $$.v = 0;
+ $$.ifpos = -1;
+ $$.f = AF_UNSPEC;
$$.a.iplookuptype = IPLT_POOL;
$$.a.iplookupsubtype = 0;
$$.a.iplookupnum = $3; }
| pool '/' YY_STR { pooled = 1;
+ $$.ifpos = -1;
+ $$.f = AF_UNSPEC;
+ $$.type = FRI_LOOKUP;
$$.a.iplookuptype = IPLT_POOL;
$$.a.iplookupsubtype = 1;
- strncpy($$.a.iplookupname, $3,
- sizeof($$.a.iplookupname));
+ $$.a.iplookupname = addname(&fr, $3);
+ }
+ | pool '=' '(' { yyexpectaddr = 1;
+ pooled = 1;
}
- | pool '=' '(' poollist ')' { pooled = 1;
+ poollist ')' { yyexpectaddr = 0;
+ $$.v = 0;
+ $$.ifpos = -1;
+ $$.f = AF_UNSPEC;
+ $$.type = FRI_LOOKUP;
$$.a.iplookuptype = IPLT_POOL;
$$.a.iplookupsubtype = 0;
- $$.a.iplookupnum = makepool($4); }
+ $$.a.iplookupnum = makepool($5);
+ }
| hash '/' YY_NUMBER { hashed = 1;
+ yyexpectaddr = 0;
+ $$.v = 0;
+ $$.ifpos = -1;
+ $$.f = AF_UNSPEC;
+ $$.type = FRI_LOOKUP;
$$.a.iplookuptype = IPLT_HASH;
$$.a.iplookupsubtype = 0;
- $$.a.iplookupnum = $3; }
- | hash '/' YY_STR { pooled = 1;
+ $$.a.iplookupnum = $3;
+ }
+ | hash '/' YY_STR { hashed = 1;
+ $$.type = FRI_LOOKUP;
+ $$.v = 0;
+ $$.ifpos = -1;
+ $$.f = AF_UNSPEC;
$$.a.iplookuptype = IPLT_HASH;
$$.a.iplookupsubtype = 1;
- strncpy($$.a.iplookupname, $3,
- sizeof($$.a.iplookupname));
+ $$.a.iplookupname = addname(&fr, $3);
}
- | hash '=' '(' addrlist ')' { hashed = 1;
+ | hash '=' '(' { hashed = 1;
+ yyexpectaddr = 1;
+ }
+ addrlist ')' { yyexpectaddr = 0;
+ $$.v = 0;
+ $$.ifpos = -1;
+ $$.f = AF_UNSPEC;
+ $$.type = FRI_LOOKUP;
$$.a.iplookuptype = IPLT_HASH;
$$.a.iplookupsubtype = 0;
- $$.a.iplookupnum = makehash($4); }
- | ipaddr { bcopy(&$1, &$$, sizeof($$));
+ $$.a.iplookupnum = makehash($5);
+ }
+ | ipaddr { $$ = $1;
yyexpectaddr = 0; }
;
ipaddr: IPFY_ANY { bzero(&($$), sizeof($$));
+ $$.type = FRI_NORMAL;
+ $$.ifpos = -1;
+ yyexpectaddr = 0;
+ }
+ | hostname { $$.a = $1.adr;
+ $$.f = $1.f;
+ if ($1.f == AF_INET6)
+ fill6bits(128, $$.m.i6);
+ else if ($1.f == AF_INET)
+ fill6bits(32, $$.m.i6);
+ $$.v = ftov($1.f);
+ $$.ifpos = dynamic;
+ $$.type = FRI_NORMAL;
+ }
+ | hostname { yyresetdict(); }
+ maskspace { yysetdict(maskwords);
+ yyexpectaddr = 2; }
+ ipmask { ntomask($1.f, $5, $$.m.i6);
+ $$.a = $1.adr;
+ $$.a.i6[0] &= $$.m.i6[0];
+ $$.a.i6[1] &= $$.m.i6[1];
+ $$.a.i6[2] &= $$.m.i6[2];
+ $$.a.i6[3] &= $$.m.i6[3];
+ $$.f = $1.f;
+ $$.v = ftov($1.f);
+ $$.type = ifpflag;
+ $$.ifpos = dynamic;
+ if (ifpflag != 0 && $$.v == 0) {
+ if (frc->fr_family == AF_INET6){
+ $$.v = 6;
+ $$.f = AF_INET6;
+ } else {
+ $$.v = 4;
+ $$.f = AF_INET;
+ }
+ }
yyresetdict();
- yyexpectaddr = 0; }
- | hostname { $$.a.in4 = $1;
- $$.m.in4_addr = 0xffffffff;
- yyexpectaddr = 0; }
- | hostname { yyresetdict();
- $$.a.in4_addr = $1.s_addr; }
- maskspace { yysetdict(maskwords); }
- ipv4mask { $$.m.in4_addr = $5.s_addr;
- $$.a.in4_addr &= $5.s_addr;
- yyresetdict();
- yyexpectaddr = 0; }
- | YY_IPV6 { bcopy(&$1, &$$.a, sizeof($$.a));
- fill6bits(128, (u_32_t *)&$$.m);
+ yyexpectaddr = 0;
+ }
+ | '(' YY_STR ')' { $$.type = FRI_DYNAMIC;
+ ifpflag = FRI_DYNAMIC;
+ $$.ifpos = addname(&fr, $2);
+ $$.lif = 0;
+ }
+ | '(' YY_STR ')' '/'
+ { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); }
+ maskopts
+ { $$.type = ifpflag;
+ $$.ifpos = addname(&fr, $2);
+ $$.lif = 0;
+ if (frc->fr_family == AF_UNSPEC)
+ frc->fr_family = AF_INET;
+ if (ifpflag == FRI_DYNAMIC) {
+ ntomask(frc->fr_family,
+ $6, $$.m.i6);
+ }
yyresetdict();
- yyexpectaddr = 0; }
- | YY_IPV6 { yyresetdict();
- bcopy(&$1, &$$.a, sizeof($$.a)); }
- maskspace { yysetdict(maskwords); }
- ipv6mask { bcopy(&$5, &$$.m, sizeof($$.m));
+ yyexpectaddr = 0;
+ }
+ | '(' YY_STR ':' YY_NUMBER ')' '/'
+ { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); }
+ maskopts
+ { $$.type = ifpflag;
+ $$.ifpos = addname(&fr, $2);
+ $$.lif = $4;
+ if (frc->fr_family == AF_UNSPEC)
+ frc->fr_family = AF_INET;
+ if (ifpflag == FRI_DYNAMIC) {
+ ntomask(frc->fr_family,
+ $8, $$.m.i6);
+ }
yyresetdict();
- yyexpectaddr = 0; }
+ yyexpectaddr = 0;
+ }
;
+
maskspace:
'/'
| IPFY_MASK
;
-ipv4mask:
- ipv4 { $$ = $1; }
- | YY_HEX { $$.s_addr = htonl($1); }
- | YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$); }
- | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) {
- $$.s_addr = 0;
+ipmask: ipv4 { $$ = count4bits($1.s_addr); }
+ | YY_HEX { $$ = count4bits(htonl($1)); }
+ | YY_NUMBER { $$ = $1; }
+ | YY_IPV6 { $$ = count6bits($1.i6); }
+ | maskopts { $$ = $1; }
+ ;
+
+maskopts:
+ IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) {
ifpflag = FRI_BROADCAST;
- } else
+ } else {
YYERROR;
+ }
+ $$ = 0;
}
| IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) {
- $$.s_addr = 0;
ifpflag = FRI_NETWORK;
- } else
+ } else {
YYERROR;
+ }
+ $$ = 0;
}
| IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) {
- $$.s_addr = 0;
ifpflag = FRI_NETMASKED;
- } else
+ } else {
YYERROR;
+ }
+ $$ = 0;
}
| IPFY_PEER { if (ifpflag == FRI_DYNAMIC) {
- $$.s_addr = 0;
ifpflag = FRI_PEERADDR;
- } else
+ } else {
YYERROR;
+ }
+ $$ = 0;
}
+ | YY_NUMBER { $$ = $1; }
;
-ipv6mask:
- YY_NUMBER { ntomask(6, $1, $$.i6); }
- | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) {
- bzero(&$$, sizeof($$));
- ifpflag = FRI_BROADCAST;
- } else
- YYERROR;
- }
- | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) {
- bzero(&$$, sizeof($$));
- ifpflag = FRI_BROADCAST;
- } else
+hostname:
+ ipv4 { $$.adr.in4 = $1;
+ if (frc->fr_family == AF_INET6)
YYERROR;
+ $$.f = AF_INET;
+ yyexpectaddr = 2;
}
- | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) {
- bzero(&$$, sizeof($$));
- ifpflag = FRI_BROADCAST;
- } else
+ | YY_NUMBER { if (frc->fr_family == AF_INET6)
YYERROR;
+ $$.adr.in4_addr = $1;
+ $$.f = AF_INET;
+ yyexpectaddr = 2;
}
- | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) {
- bzero(&$$, sizeof($$));
- ifpflag = FRI_BROADCAST;
- } else
+ | YY_HEX { if (frc->fr_family == AF_INET6)
YYERROR;
+ $$.adr.in4_addr = $1;
+ $$.f = AF_INET;
+ yyexpectaddr = 2;
}
- ;
-
-hostname:
- ipv4 { $$ = $1; }
- | YY_NUMBER { $$.s_addr = $1; }
- | YY_HEX { $$.s_addr = $1; }
- | YY_STR { $$.s_addr = lookuphost($1);
+ | YY_STR { if (lookuphost($1, &$$.adr) == 0)
+ $$.f = AF_INET;
free($1);
+ yyexpectaddr = 2;
+ }
+ | YY_IPV6 { if (frc->fr_family == AF_INET)
+ YYERROR;
+ $$.adr = $1;
+ $$.f = AF_INET6;
+ yyexpectaddr = 2;
}
;
addrlist:
ipaddr { $$ = newalist(NULL);
- bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a));
- bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); }
- | addrlist ',' ipaddr
- { $$ = newalist($1);
- bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a));
- bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); }
+ $$->al_family = $1.f;
+ $$->al_i6addr = $1.a;
+ $$->al_i6mask = $1.m;
+ }
+ | ipaddr ',' { yyexpectaddr = 1; } addrlist
+ { $$ = newalist($4);
+ $$->al_family = $1.f;
+ $$->al_i6addr = $1.a;
+ $$->al_i6mask = $1.m;
+ }
;
pool: IPFY_POOL { yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
@@ -1010,53 +1195,70 @@ hash: IPFY_HASH { yyexpectaddr = 0; yycont = NULL; yyresetdict(); }
poollist:
ipaddr { $$ = newalist(NULL);
- bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a));
- bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); }
+ $$->al_family = $1.f;
+ $$->al_i6addr = $1.a;
+ $$->al_i6mask = $1.m;
+ }
| '!' ipaddr { $$ = newalist(NULL);
$$->al_not = 1;
- bcopy(&($2.a), &($$->al_i6addr), sizeof($2.a));
- bcopy(&($2.m), &($$->al_i6mask), sizeof($2.m)); }
+ $$->al_family = $2.f;
+ $$->al_i6addr = $2.a;
+ $$->al_i6mask = $2.m;
+ }
| poollist ',' ipaddr
{ $$ = newalist($1);
- bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a));
- bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); }
+ $$->al_family = $3.f;
+ $$->al_i6addr = $3.a;
+ $$->al_i6mask = $3.m;
+ }
| poollist ',' '!' ipaddr
{ $$ = newalist($1);
$$->al_not = 1;
- bcopy(&($4.a), &($$->al_i6addr), sizeof($4.a));
- bcopy(&($4.m), &($$->al_i6mask), sizeof($4.m)); }
+ $$->al_family = $4.f;
+ $$->al_i6addr = $4.a;
+ $$->al_i6mask = $4.m;
+ }
;
port: IPFY_PORT { yyexpectaddr = 0;
yycont = NULL;
+ if (frc->fr_proto != 0 &&
+ frc->fr_proto != IPPROTO_UDP &&
+ frc->fr_proto != IPPROTO_TCP)
+ yyerror("port use incorrect");
}
;
portc: port compare { $$ = $2;
- yysetdict(NULL); }
+ yysetdict(NULL);
+ }
| porteq { $$ = $1; }
;
porteq: port '=' { $$ = FR_EQUAL;
- yysetdict(NULL); }
+ yysetdict(NULL);
+ }
;
portr: IPFY_PORT { yyexpectaddr = 0;
yycont = NULL;
- yysetdict(NULL); }
+ yysetdict(NULL);
+ }
;
portcomp:
portc portnum { $$.pc = $1;
$$.p1 = $2;
- yyresetdict(); }
+ yyresetdict();
+ }
;
portrange:
portr portnum range portnum { $$.p1 = $2;
$$.pc = $3;
$$.p2 = $4;
- yyresetdict(); }
+ yyresetdict();
+ }
;
icmp: | itype icode
@@ -1070,8 +1272,30 @@ itype: seticmptype icmptype
;
seticmptype:
- IPFY_ICMPTYPE { setipftype();
- yysetdict(icmptypewords); }
+ IPFY_ICMPTYPE { if (frc->fr_family == AF_UNSPEC)
+ frc->fr_family = AF_INET;
+ if (frc->fr_family == AF_INET &&
+ frc->fr_type == FR_T_IPF &&
+ frc->fr_proto != IPPROTO_ICMP) {
+ yyerror("proto not icmp");
+ }
+ if (frc->fr_family == AF_INET6 &&
+ frc->fr_type == FR_T_IPF &&
+ frc->fr_proto != IPPROTO_ICMPV6) {
+ yyerror("proto not ipv6-icmp");
+ }
+ setipftype();
+ DOALL(if (fr->fr_family == AF_INET) { \
+ fr->fr_ip.fi_v = 4; \
+ fr->fr_mip.fi_v = 0xf; \
+ }
+ if (fr->fr_family == AF_INET6) { \
+ fr->fr_ip.fi_v = 6; \
+ fr->fr_mip.fi_v = 0xf; \
+ }
+ )
+ yysetdict(NULL);
+ }
;
icode: | seticmpcode icmpcode
@@ -1146,9 +1370,18 @@ stateopt:
IPFY_LIMIT YY_NUMBER { DOALL(fr->fr_statemax = $2;) }
| IPFY_STRICT { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
YYERROR; \
- } else \
+ } else if (fr->fr_flags & FR_STLOOSE) {\
+ YYERROR; \
+ } else \
fr->fr_flags |= FR_STSTRICT;)
}
+ | IPFY_LOOSE { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
+ YYERROR; \
+ } else if (fr->fr_flags & FR_STSTRICT){\
+ YYERROR; \
+ } else \
+ fr->fr_flags |= FR_STLOOSE;)
+ }
| IPFY_NEWISN { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \
YYERROR; \
} else \
@@ -1162,10 +1395,32 @@ stateopt:
| IPFY_AGE YY_NUMBER '/' YY_NUMBER
{ DOALL(fr->fr_age[0] = $2; \
fr->fr_age[1] = $4;) }
+ | IPFY_ICMPHEAD groupname
+ { DOALL(seticmphead(&fr, $2);)
+ free($2);
+ }
+ | IPFY_NOLOG
+ { DOALL(fr->fr_nostatelog = 1;) }
+ | IPFY_RPC
+ { DOALL(fr->fr_rpc = 1;) }
+ | IPFY_RPC IPFY_IN YY_STR
+ { DOALL(fr->fr_rpc = 1;) }
+ | IPFY_MAX_SRCS YY_NUMBER
+ { DOALL(fr->fr_srctrack.ht_max_nodes = $2;) }
+ | IPFY_MAX_PER_SRC YY_NUMBER
+ { DOALL(fr->fr_srctrack.ht_max_per_node = $2; \
+ fr->fr_srctrack.ht_netmask = \
+ fr->fr_family == AF_INET ? 32: 128;)
+ }
+ | IPFY_MAX_PER_SRC YY_NUMBER '/' YY_NUMBER
+ { DOALL(fr->fr_srctrack.ht_max_per_node = $2; \
+ fr->fr_srctrack.ht_netmask = $4;)
+ }
;
portnum:
- servicename { if (getport(frc, $1, &($$)) == -1)
+ servicename { if (getport(frc, $1,
+ &($$), NULL) == -1)
yyerror("service unknown");
$$ = ntohs($$);
free($1);
@@ -1188,14 +1443,14 @@ withopt:
| notwith opttype { DOALL(fr->fr_mflx |= $2;) }
| ipopt ipopts { yyresetdict(); }
| notwith ipopt ipopts { yyresetdict(); }
- | startv6hdrs ipv6hdrs { yyresetdict(); }
+ | startv6hdr ipv6hdrs { yyresetdict(); }
;
ipopt: IPFY_OPT { yysetdict(ipv4optwords); }
;
-startv6hdrs:
- IPF6_V6HDRS { if (use_inet6 == 0)
+startv6hdr:
+ IPFY_V6HDR { if (frc->fr_family != AF_INET6)
yyerror("only available with IPv6");
yysetdict(ipv6optwords);
}
@@ -1222,9 +1477,18 @@ opttype:
| IPFY_BROADCAST { $$ = FI_BROADCAST; }
| IPFY_STATE { $$ = FI_STATE; }
| IPFY_OOW { $$ = FI_OOW; }
+ | IPFY_AH { $$ = FI_AH; }
+ | IPFY_V6HDRS { $$ = FI_V6EXTHDR; }
;
ipopts: optlist { DOALL(fr->fr_mip.fi_optmsk |= $1;
+ if (fr->fr_family == AF_UNSPEC) {
+ fr->fr_family = AF_INET;
+ fr->fr_ip.fi_v = 4;
+ fr->fr_mip.fi_v = 0xf;
+ } else if (fr->fr_family != AF_INET) {
+ YYERROR;
+ }
if (!nowith)
fr->fr_ip.fi_optmsk |= $1;)
}
@@ -1264,22 +1528,11 @@ seclevel:
;
icmptype:
- YY_NUMBER { $$ = $1; }
- | IPFY_ICMPT_UNR { $$ = ICMP_UNREACH; }
- | IPFY_ICMPT_ECHO { $$ = ICMP_ECHO; }
- | IPFY_ICMPT_ECHOR { $$ = ICMP_ECHOREPLY; }
- | IPFY_ICMPT_SQUENCH { $$ = ICMP_SOURCEQUENCH; }
- | IPFY_ICMPT_REDIR { $$ = ICMP_REDIRECT; }
- | IPFY_ICMPT_TIMEX { $$ = ICMP_TIMXCEED; }
- | IPFY_ICMPT_PARAMP { $$ = ICMP_PARAMPROB; }
- | IPFY_ICMPT_TIMEST { $$ = ICMP_TSTAMP; }
- | IPFY_ICMPT_TIMESTREP { $$ = ICMP_TSTAMPREPLY; }
- | IPFY_ICMPT_INFOREQ { $$ = ICMP_IREQ; }
- | IPFY_ICMPT_INFOREP { $$ = ICMP_IREQREPLY; }
- | IPFY_ICMPT_MASKREQ { $$ = ICMP_MASKREQ; }
- | IPFY_ICMPT_MASKREP { $$ = ICMP_MASKREPLY; }
- | IPFY_ICMPT_ROUTERAD { $$ = ICMP_ROUTERADVERT; }
- | IPFY_ICMPT_ROUTERSOL { $$ = ICMP_ROUTERSOLICIT; }
+ YY_NUMBER { $$ = $1; }
+ | YY_STR { $$ = geticmptype(frc->fr_family, $1);
+ if ($$ == -1)
+ yyerror("unrecognised icmp type");
+ }
;
icmpcode:
@@ -1314,7 +1567,8 @@ opt:
| IPFY_IPOPT_SEC { $$ = getoptbyvalue(IPOPT_SECURITY); }
| IPFY_IPOPT_LSRR { $$ = getoptbyvalue(IPOPT_LSRR); }
| IPFY_IPOPT_ESEC { $$ = getoptbyvalue(IPOPT_E_SEC); }
- | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); }
+ | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); }
+ | IPFY_IPOPT_CIPSO doi { $$ = getoptbyvalue(IPOPT_CIPSO); }
| IPFY_IPOPT_SATID { $$ = getoptbyvalue(IPOPT_SATID); }
| IPFY_IPOPT_SSRR { $$ = getoptbyvalue(IPOPT_SSRR); }
| IPFY_IPOPT_ADDEXT { $$ = getoptbyvalue(IPOPT_ADDEXT); }
@@ -1329,6 +1583,13 @@ opt:
| IPFY_IPOPT_UMP { $$ = getoptbyvalue(IPOPT_UMP); }
| setsecclass secname
{ DOALL(fr->fr_mip.fi_secmsk |= $2;
+ if (fr->fr_family == AF_UNSPEC) {
+ fr->fr_family = AF_INET;
+ fr->fr_ip.fi_v = 4;
+ fr->fr_mip.fi_v = 0xf;
+ } else if (fr->fr_family != AF_INET) {
+ YYERROR;
+ }
if (!nowith)
fr->fr_ip.fi_secmsk |= $2;)
$$ = 0;
@@ -1337,7 +1598,15 @@ opt:
;
setsecclass:
- IPFY_SECCLASS { yysetdict(ipv4secwords); }
+ IPFY_SECCLASS { yysetdict(ipv4secwords); }
+ ;
+
+doi: IPFY_DOI YY_NUMBER { DOALL(fr->fr_doimask = 0xffffffff; \
+ if (!nowith) \
+ fr->fr_doi = $2;) }
+ | IPFY_DOI YY_HEX { DOALL(fr->fr_doimask = 0xffffffff; \
+ if (!nowith) \
+ fr->fr_doi = $2;) }
;
ipv6hdr:
@@ -1463,7 +1732,7 @@ ipv4: ipv4_24 '.' YY_NUMBER
%%
-static struct wordtab ipfwords[95] = {
+static struct wordtab ipfwords[] = {
{ "age", IPFY_AGE },
{ "ah", IPFY_AH },
{ "all", IPFY_ALL },
@@ -1481,10 +1750,16 @@ static struct wordtab ipfwords[95] = {
#endif
{ "call", IPFY_CALL },
{ "code", IPFY_ICMPCODE },
+ { "comment", IPFY_COMMENT },
{ "count", IPFY_COUNT },
+ { "decapsulate", IPFY_DECAPS },
+ { "dstlist", IPFY_DSTLIST },
+ { "doi", IPFY_DOI },
{ "dup-to", IPFY_DUPTO },
{ "eq", YY_CMP_EQ },
{ "esp", IPFY_ESP },
+ { "exp", IPFY_IPFEXPR },
+ { "family", IPFY_FAMILY },
{ "fastroute", IPFY_FROUTE },
{ "first", IPFY_FIRST },
{ "flags", IPFY_FLAGS },
@@ -1497,20 +1772,27 @@ static struct wordtab ipfwords[95] = {
{ "gt", YY_CMP_GT },
{ "head", IPFY_HEAD },
{ "icmp", IPFY_ICMP },
+ { "icmp-head", IPFY_ICMPHEAD },
{ "icmp-type", IPFY_ICMPTYPE },
{ "in", IPFY_IN },
{ "in-via", IPFY_INVIA },
+ { "inet", IPFY_INET },
+ { "inet6", IPFY_INET6 },
{ "ipopt", IPFY_IPOPTS },
{ "ipopts", IPFY_IPOPTS },
{ "keep", IPFY_KEEP },
+ { "l5-as", IPFY_L5AS },
{ "le", YY_CMP_LE },
{ "level", IPFY_LEVEL },
{ "limit", IPFY_LIMIT },
{ "log", IPFY_LOG },
+ { "loose", IPFY_LOOSE },
{ "lowttl", IPFY_LOWTTL },
{ "lt", YY_CMP_LT },
{ "mask", IPFY_MASK },
{ "match-tag", IPFY_MATCHTAG },
+ { "max-per-src", IPFY_MAX_PER_SRC },
+ { "max-srcs", IPFY_MAX_SRCS },
{ "mbcast", IPFY_MBCAST },
{ "mcast", IPFY_MULTICAST },
{ "multicast", IPFY_MULTICAST },
@@ -1520,6 +1802,7 @@ static struct wordtab ipfwords[95] = {
{ "newisn", IPFY_NEWISN },
{ "no", IPFY_NO },
{ "no-icmp-err", IPFY_NOICMPERR },
+ { "nolog", IPFY_NOLOG },
{ "nomatch", IPFY_NOMATCH },
{ "now", IPFY_NOW },
{ "not", IPFY_NOT },
@@ -1540,7 +1823,10 @@ static struct wordtab ipfwords[95] = {
{ "return-icmp-as-dest", IPFY_RETICMPASDST },
{ "return-rst", IPFY_RETRST },
{ "route-to", IPFY_ROUTETO },
+ { "rule-ttl", IPFY_RULETTL },
+ { "rpc", IPFY_RPC },
{ "sec-class", IPFY_SECCLASS },
+ { "set", IPFY_SET },
{ "set-tag", IPFY_SETTAG },
{ "skip", IPFY_SKIP },
{ "short", IPFY_SHORT },
@@ -1554,19 +1840,20 @@ static struct wordtab ipfwords[95] = {
{ "to", IPFY_TO },
{ "ttl", IPFY_TTL },
{ "udp", IPFY_UDP },
- { "v6hdrs", IPF6_V6HDRS },
+ { "v6hdr", IPFY_V6HDR },
+ { "v6hdrs", IPFY_V6HDRS },
{ "with", IPFY_WITH },
{ NULL, 0 }
};
-static struct wordtab addrwords[4] = {
+static struct wordtab addrwords[] = {
{ "any", IPFY_ANY },
{ "hash", IPFY_HASH },
{ "pool", IPFY_POOL },
{ NULL, 0 }
};
-static struct wordtab maskwords[5] = {
+static struct wordtab maskwords[] = {
{ "broadcast", IPFY_BROADCAST },
{ "netmasked", IPFY_NETMASKED },
{ "network", IPFY_NETWORK },
@@ -1574,26 +1861,7 @@ static struct wordtab maskwords[5] = {
{ NULL, 0 }
};
-static struct wordtab icmptypewords[16] = {
- { "echo", IPFY_ICMPT_ECHO },
- { "echorep", IPFY_ICMPT_ECHOR },
- { "inforeq", IPFY_ICMPT_INFOREQ },
- { "inforep", IPFY_ICMPT_INFOREP },
- { "maskrep", IPFY_ICMPT_MASKREP },
- { "maskreq", IPFY_ICMPT_MASKREQ },
- { "paramprob", IPFY_ICMPT_PARAMP },
- { "redir", IPFY_ICMPT_REDIR },
- { "unreach", IPFY_ICMPT_UNR },
- { "routerad", IPFY_ICMPT_ROUTERAD },
- { "routersol", IPFY_ICMPT_ROUTERSOL },
- { "squench", IPFY_ICMPT_SQUENCH },
- { "timest", IPFY_ICMPT_TIMEST },
- { "timestrep", IPFY_ICMPT_TIMESTREP },
- { "timex", IPFY_ICMPT_TIMEX },
- { NULL, 0 },
-};
-
-static struct wordtab icmpcodewords[17] = {
+static struct wordtab icmpcodewords[] = {
{ "cutoff-preced", IPFY_ICMPC_CUTPRE },
{ "filter-prohib", IPFY_ICMPC_FLTPRO },
{ "isolate", IPFY_ICMPC_ISOLATE },
@@ -1613,7 +1881,7 @@ static struct wordtab icmpcodewords[17] = {
{ NULL, 0 },
};
-static struct wordtab ipv4optwords[25] = {
+static struct wordtab ipv4optwords[] = {
{ "addext", IPFY_IPOPT_ADDEXT },
{ "cipso", IPFY_IPOPT_CIPSO },
{ "dps", IPFY_IPOPT_DPS },
@@ -1641,7 +1909,7 @@ static struct wordtab ipv4optwords[25] = {
{ NULL, 0 },
};
-static struct wordtab ipv4secwords[9] = {
+static struct wordtab ipv4secwords[] = {
{ "confid", IPFY_SEC_CONF },
{ "reserv-1", IPFY_SEC_RSV1 },
{ "reserv-2", IPFY_SEC_RSV2 },
@@ -1653,7 +1921,7 @@ static struct wordtab ipv4secwords[9] = {
{ NULL, 0 },
};
-static struct wordtab ipv6optwords[9] = {
+static struct wordtab ipv6optwords[] = {
{ "dstopts", IPFY_IPV6OPT_DSTOPTS },
{ "esp", IPFY_IPV6OPT_ESP },
{ "frag", IPFY_IPV6OPT_FRAG },
@@ -1665,7 +1933,7 @@ static struct wordtab ipv6optwords[9] = {
{ NULL, 0 },
};
-static struct wordtab logwords[33] = {
+static struct wordtab logwords[] = {
{ "kern", IPFY_FAC_KERN },
{ "user", IPFY_FAC_USER },
{ "mail", IPFY_FAC_MAIL },
@@ -1751,7 +2019,7 @@ FILE *fp;
ipffd = fd;
for (i = 0; i <= IPL_LOGMAX; i++)
- ipfioctl[i] = iocfuncs[i];
+ ipfioctls[i] = iocfuncs[i];
ipfaddfunc = addfunc;
if (feof(fp))
@@ -1779,23 +2047,29 @@ static void newrule()
{
frentry_t *frn;
- frn = (frentry_t *)calloc(1, sizeof(frentry_t));
+ frn = allocfr();
for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next)
;
- if (fr != NULL)
+ if (fr != NULL) {
fr->fr_next = frn;
- if (frtop == NULL)
+ frn->fr_pnext = &fr->fr_next;
+ }
+ if (frtop == NULL) {
frtop = frn;
+ frn->fr_pnext = &frtop;
+ }
fr = frn;
frc = frn;
fr->fr_loglevel = 0xffff;
fr->fr_isc = (void *)-1;
fr->fr_logtag = FR_NOLOGTAG;
fr->fr_type = FR_T_NONE;
- if (use_inet6 != 0)
- fr->fr_v = 6;
- else
- fr->fr_v = 4;
+ fr->fr_flineno = yylineNum;
+
+ if (use_inet6 == 1)
+ fr->fr_family = AF_INET6;
+ else if (use_inet6 == -1)
+ fr->fr_family = AF_INET;
nrules = 1;
}
@@ -1808,7 +2082,13 @@ static void setipftype()
fr->fr_type = FR_T_IPF;
fr->fr_data = (void *)calloc(sizeof(fripf_t), 1);
fr->fr_dsize = sizeof(fripf_t);
- fr->fr_ip.fi_v = frc->fr_v;
+ fr->fr_family = frc->fr_family;
+ if (fr->fr_family == AF_INET) {
+ fr->fr_ip.fi_v = 4;
+ }
+ else if (fr->fr_family == AF_INET6) {
+ fr->fr_ip.fi_v = 6;
+ }
fr->fr_mip.fi_v = 0xf;
fr->fr_ipf->fri_sifpidx = -1;
fr->fr_ipf->fri_difpidx = -1;
@@ -1831,10 +2111,13 @@ static frentry_t *addrule()
count = nrules;
f = f2;
for (f1 = frc; count > 0; count--, f1 = f1->fr_next) {
- f->fr_next = (frentry_t *)calloc(sizeof(*f), 1);
+ f->fr_next = allocfr();
+ if (f->fr_next == NULL)
+ return NULL;
+ f->fr_next->fr_pnext = &f->fr_next;
added++;
f = f->fr_next;
- bcopy(f1, f, sizeof(*f));
+ *f = *f1;
f->fr_next = NULL;
if (f->fr_caddr != NULL) {
f->fr_caddr = malloc(f->fr_dsize);
@@ -1846,10 +2129,11 @@ static frentry_t *addrule()
}
-static u_32_t lookuphost(name)
-char *name;
+static int
+lookuphost(name, addrp)
+ char *name;
+ i6addr_t *addrp;
{
- u_32_t addr;
int i;
hashed = 0;
@@ -1857,19 +2141,20 @@ char *name;
dynamic = -1;
for (i = 0; i < 4; i++) {
- if (strncmp(name, frc->fr_ifnames[i],
- sizeof(frc->fr_ifnames[i])) == 0) {
+ if (fr->fr_ifnames[i] == -1)
+ continue;
+ if (strcmp(name, fr->fr_names + fr->fr_ifnames[i]) == 0) {
ifpflag = FRI_DYNAMIC;
- dynamic = i;
- return 0;
+ dynamic = addname(&fr, name);
+ return 1;
}
}
- if (gethost(name, &addr) == -1) {
+ if (gethost(AF_INET, name, addrp) == -1) {
fprintf(stderr, "unknown name \"%s\"\n", name);
- return 0;
+ return -1;
}
- return addr;
+ return 0;
}
@@ -1891,7 +2176,7 @@ char *phrase;
fprintf(stderr, "cannot mix IPF and BPF matching\n");
return;
}
- fr->fr_v = v;
+ fr->fr_family = vtof(v);
fr->fr_type = FR_T_BPFOPC;
if (!strncmp(phrase, "0x", 2)) {
@@ -1986,8 +2271,9 @@ alist_t *ptr;
}
-static int makepool(list)
-alist_t *list;
+static int
+makepool(list)
+ alist_t *list;
{
ip_pool_node_t *n, *top;
ip_pool_t pool;
@@ -1999,10 +2285,30 @@ alist_t *list;
top = calloc(1, sizeof(*top));
if (top == NULL)
return 0;
-
+
for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
- n->ipn_addr.adf_addr.in4.s_addr = a->al_1;
- n->ipn_mask.adf_addr.in4.s_addr = a->al_2;
+ if (use_inet6 == 1) {
+#ifdef AF_INET6
+ n->ipn_addr.adf_family = AF_INET6;
+ n->ipn_addr.adf_addr = a->al_i6addr;
+ n->ipn_addr.adf_len = offsetof(addrfamily_t,
+ adf_addr) + 16;
+ n->ipn_mask.adf_family = AF_INET6;
+ n->ipn_mask.adf_addr = a->al_i6mask;
+ n->ipn_mask.adf_len = offsetof(addrfamily_t,
+ adf_addr) + 16;
+
+#endif
+ } else {
+ n->ipn_addr.adf_family = AF_INET;
+ n->ipn_addr.adf_addr.in4.s_addr = a->al_1;
+ n->ipn_addr.adf_len = offsetof(addrfamily_t,
+ adf_addr) + 4;
+ n->ipn_mask.adf_family = AF_INET;
+ n->ipn_mask.adf_addr.in4.s_addr = a->al_2;
+ n->ipn_mask.adf_len = offsetof(addrfamily_t,
+ adf_addr) + 4;
+ }
n->ipn_info = a->al_not;
if (a->al_next != NULL) {
n->ipn_next = calloc(1, sizeof(*n));
@@ -2013,7 +2319,7 @@ alist_t *list;
bzero((char *)&pool, sizeof(pool));
pool.ipo_unit = IPL_LOGIPF;
pool.ipo_list = top;
- num = load_pool(&pool, ipfioctl[IPL_LOGLOOKUP]);
+ num = load_pool(&pool, ipfioctls[IPL_LOGLOOKUP]);
while ((n = top) != NULL) {
top = n->ipn_next;
@@ -2036,10 +2342,17 @@ alist_t *list;
top = calloc(1, sizeof(*top));
if (top == NULL)
return 0;
-
+
for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) {
- n->ipe_addr.in4_addr = a->al_1;
- n->ipe_mask.in4_addr = a->al_2;
+ if (a->al_family == AF_INET6) {
+ n->ipe_family = AF_INET6;
+ n->ipe_addr = a->al_i6addr;
+ n->ipe_mask = a->al_i6mask;
+ } else {
+ n->ipe_family = AF_INET;
+ n->ipe_addr.in4_addr = a->al_1;
+ n->ipe_mask.in4_addr = a->al_2;
+ }
n->ipe_value = 0;
if (a->al_next != NULL) {
n->ipe_next = calloc(1, sizeof(*n));
@@ -2052,7 +2365,7 @@ alist_t *list;
iph.iph_type = IPHASH_LOOKUP;
*iph.iph_name = '\0';
- if (load_hash(&iph, top, ipfioctl[IPL_LOGLOOKUP]) == 0)
+ if (load_hash(&iph, top, ipfioctls[IPL_LOGLOOKUP]) == 0)
sscanf(iph.iph_name, "%u", &num);
else
num = 0;
@@ -2065,7 +2378,7 @@ alist_t *list;
}
-void ipf_addrule(fd, ioctlfunc, ptr)
+int ipf_addrule(fd, ioctlfunc, ptr)
int fd;
ioctlfunc_t ioctlfunc;
void *ptr;
@@ -2075,7 +2388,7 @@ void *ptr;
ipfobj_t obj;
if (ptr == NULL)
- return;
+ return 0;
fr = ptr;
add = 0;
@@ -2083,7 +2396,7 @@ void *ptr;
bzero((char *)&obj, sizeof(obj));
obj.ipfo_rev = IPFILTER_VERSION;
- obj.ipfo_size = sizeof(*fr);
+ obj.ipfo_size = fr->fr_size;
obj.ipfo_type = IPFOBJ_FRENTRY;
obj.ipfo_ptr = ptr;
@@ -2118,8 +2431,11 @@ void *ptr;
if ((opts & OPT_ZERORULEST) != 0) {
if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
if ((opts & OPT_DONOTHING) == 0) {
- fprintf(stderr, "%d:", yylineNum);
- perror("ioctl(SIOCZRLST)");
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(zero rule)",
+ fr->fr_flineno);
+ return ipf_perror_fd(fd, ioctlfunc, msg);
}
} else {
#ifdef USE_QUAD_T
@@ -2134,19 +2450,26 @@ void *ptr;
}
} else if ((opts & OPT_REMOVE) != 0) {
if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
- if ((opts & OPT_DONOTHING) != 0) {
- fprintf(stderr, "%d:", yylineNum);
- perror("ioctl(delete rule)");
+ if ((opts & OPT_DONOTHING) == 0) {
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(delete rule)",
+ fr->fr_flineno);
+ return ipf_perror_fd(fd, ioctlfunc, msg);
}
}
} else {
if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
- if (!(opts & OPT_DONOTHING)) {
- fprintf(stderr, "%d:", yylineNum);
- perror("ioctl(add/insert rule)");
+ if ((opts & OPT_DONOTHING) == 0) {
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(add/insert rule)",
+ fr->fr_flineno);
+ return ipf_perror_fd(fd, ioctlfunc, msg);
}
}
}
+ return 0;
}
static void setsyslog()
@@ -2168,9 +2491,16 @@ frentry_t *fr;
{
frentry_t *f;
- for (f = frold; f != NULL; f = f->fr_next)
- if (strncmp(f->fr_grhead, fr->fr_group, FR_GROUPLEN) == 0)
+ for (f = frold; f != NULL; f = f->fr_next) {
+ if (f->fr_grhead == -1 && fr->fr_group == -1)
break;
+ if (f->fr_grhead == -1 || fr->fr_group == -1)
+ continue;
+ if (strcmp(f->fr_names + f->fr_grhead,
+ fr->fr_names + fr->fr_group) == 0)
+ break;
+ }
+
if (f == NULL)
return;
@@ -2183,8 +2513,8 @@ frentry_t *fr;
if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF)
return;
- if (fr->fr_v == 0 && f->fr_v != 0)
- fr->fr_v = f->fr_v;
+ if (fr->fr_family == 0 && f->fr_family != 0)
+ fr->fr_family = f->fr_family;
if (fr->fr_mproto == 0 && f->fr_mproto != 0)
fr->fr_mproto = f->fr_mproto;
@@ -2192,6 +2522,218 @@ frentry_t *fr;
fr->fr_proto = f->fr_proto;
if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) &&
- ((f->fr_flx & FI_TCPUDP) != 0))
+ ((f->fr_flx & FI_TCPUDP) != 0)) {
fr->fr_flx |= FI_TCPUDP;
+ fr->fr_mflx |= FI_TCPUDP;
+ }
+}
+
+
+static void doipfexpr(line)
+char *line;
+{
+ int *array;
+ char *error;
+
+ array = parseipfexpr(line, &error);
+ if (array == NULL) {
+ fprintf(stderr, "%s:", error);
+ yyerror("error parsing ipf matching expression");
+ return;
+ }
+
+ fr->fr_type = FR_T_IPFEXPR;
+ fr->fr_data = array;
+ fr->fr_dsize = array[0] * sizeof(*array);
+}
+
+
+static void do_tuneint(varname, value)
+char *varname;
+int value;
+{
+ char buffer[80];
+
+ strncpy(buffer, varname, 60);
+ buffer[59] = '\0';
+ strcat(buffer, "=");
+ sprintf(buffer, "%u", value);
+ ipf_dotuning(ipffd, buffer, ioctl);
+}
+
+
+static void do_tunestr(varname, value)
+char *varname, *value;
+{
+
+ if (!strcasecmp(value, "true")) {
+ do_tuneint(varname, 1);
+ } else if (!strcasecmp(value, "false")) {
+ do_tuneint(varname, 0);
+ } else {
+ yyerror("did not find true/false where expected");
+ }
+}
+
+
+static void setifname(frp, idx, name)
+frentry_t **frp;
+int idx;
+char *name;
+{
+ int pos;
+
+ pos = addname(frp, name);
+ if (pos == -1)
+ return;
+ (*frp)->fr_ifnames[idx] = pos;
+}
+
+
+static int addname(frp, name)
+frentry_t **frp;
+char *name;
+{
+ frentry_t *f;
+ int nlen;
+ int pos;
+
+ nlen = strlen(name) + 1;
+ f = realloc(*frp, (*frp)->fr_size + nlen);
+ if (*frp == frc)
+ frc = f;
+ *frp = f;
+ if (f == NULL)
+ return -1;
+ if (f->fr_pnext != NULL)
+ *f->fr_pnext = f;
+ f->fr_size += nlen;
+ pos = f->fr_namelen;
+ f->fr_namelen += nlen;
+ strcpy(f->fr_names + pos, name);
+ f->fr_names[f->fr_namelen] = '\0';
+ return pos;
+}
+
+
+static frentry_t *allocfr()
+{
+ frentry_t *fr;
+
+ fr = calloc(1, sizeof(*fr));
+ if (fr != NULL) {
+ fr->fr_size = sizeof(*fr);
+ fr->fr_comment = -1;
+ fr->fr_group = -1;
+ fr->fr_grhead = -1;
+ fr->fr_icmphead = -1;
+ fr->fr_ifnames[0] = -1;
+ fr->fr_ifnames[1] = -1;
+ fr->fr_ifnames[2] = -1;
+ fr->fr_ifnames[3] = -1;
+ fr->fr_tif.fd_name = -1;
+ fr->fr_rif.fd_name = -1;
+ fr->fr_dif.fd_name = -1;
+ }
+ return fr;
+}
+
+
+static void setgroup(frp, name)
+frentry_t **frp;
+char *name;
+{
+ int pos;
+
+ pos = addname(frp, name);
+ if (pos == -1)
+ return;
+ (*frp)->fr_group = pos;
+}
+
+
+static void setgrhead(frp, name)
+frentry_t **frp;
+char *name;
+{
+ int pos;
+
+ pos = addname(frp, name);
+ if (pos == -1)
+ return;
+ (*frp)->fr_grhead = pos;
+}
+
+
+static void seticmphead(frp, name)
+frentry_t **frp;
+char *name;
+{
+ int pos;
+
+ pos = addname(frp, name);
+ if (pos == -1)
+ return;
+ (*frp)->fr_icmphead = pos;
+}
+
+
+static void
+build_dstaddr_af(fp, ptr)
+ frentry_t *fp;
+ void *ptr;
+{
+ struct ipp_s *ipp = ptr;
+ frentry_t *f = fp;
+
+ if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) {
+ ipp->f = f->fr_family;
+ ipp->v = f->fr_ip.fi_v;
+ }
+ if (ipp->f == AF_INET)
+ ipp->v = 4;
+ else if (ipp->f == AF_INET6)
+ ipp->v = 6;
+
+ for (; f != NULL; f = f->fr_next) {
+ f->fr_ip.fi_dst = ipp->a;
+ f->fr_mip.fi_dst = ipp->m;
+ f->fr_family = ipp->f;
+ f->fr_ip.fi_v = ipp->v;
+ f->fr_mip.fi_v = 0xf;
+ f->fr_datype = ipp->type;
+ if (ipp->ifpos != -1)
+ f->fr_ipf->fri_difpidx = ipp->ifpos;
+ }
+ fr = NULL;
+}
+
+
+static void
+build_srcaddr_af(fp, ptr)
+ frentry_t *fp;
+ void *ptr;
+{
+ struct ipp_s *ipp = ptr;
+ frentry_t *f = fp;
+
+ if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) {
+ ipp->f = f->fr_family;
+ ipp->v = f->fr_ip.fi_v;
+ }
+ if (ipp->f == AF_INET)
+ ipp->v = 4;
+ else if (ipp->f == AF_INET6)
+ ipp->v = 6;
+
+ for (; f != NULL; f = f->fr_next) {
+ f->fr_ip.fi_src = ipp->a;
+ f->fr_mip.fi_src = ipp->m;
+ f->fr_family = ipp->f;
+ f->fr_ip.fi_v = ipp->v;
+ f->fr_mip.fi_v = 0xf;
+ f->fr_satype = ipp->type;
+ f->fr_ipf->fri_sifpidx = ipp->ifpos;
+ }
+ fr = NULL;
}
diff --git a/contrib/ipfilter/tools/ipfcomp.c b/contrib/ipfilter/tools/ipfcomp.c
index e00fe84a9af3..eba28ceb1d51 100644
--- a/contrib/ipfilter/tools/ipfcomp.c
+++ b/contrib/ipfilter/tools/ipfcomp.c
@@ -1,13 +1,13 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2005 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.24.2.7 2007/05/01 22:15:00 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
#include "ipf.h"
@@ -63,7 +63,7 @@ static FILE *cfile = NULL;
* required.
*/
void printc(fr)
-frentry_t *fr;
+ frentry_t *fr;
{
fripf_t *ipf;
u_long *ulp;
@@ -71,7 +71,7 @@ frentry_t *fr;
FILE *fp;
int i;
- if (fr->fr_v != 4)
+ if (fr->fr_family == 6)
return;
if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE))
return;
@@ -87,7 +87,7 @@ frentry_t *fr;
fp = cfile;
if (count == 0) {
fprintf(fp, "/*\n");
- fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n");
+ fprintf(fp, "* Copyright (C) 2012 by Darren Reed.\n");
fprintf(fp, "*\n");
fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n");
fprintf(fp, "* provided that this notice is preserved and due credit is given\n");
@@ -136,6 +136,9 @@ frentry_t *fr;
fprintf(fp, "#endif /* _KERNEL */\n");
fprintf(fp, "\n");
fprintf(fp, "#ifdef IPFILTER_COMPILED\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "extern ipf_main_softc_t ipfmain;\n");
+ fprintf(fp, "\n");
}
addrule(fp, fr);
@@ -162,12 +165,14 @@ static frgroup_t *groups = NULL;
static void addrule(fp, fr)
-FILE *fp;
-frentry_t *fr;
+ FILE *fp;
+ frentry_t *fr;
{
frentry_t *f, **fpp;
frgroup_t *g;
u_long *ulp;
+ char *ghead;
+ char *gname;
char *and;
int i;
@@ -180,8 +185,10 @@ frentry_t *fr;
}
f->fr_next = NULL;
+ gname = FR_NAME(fr, fr_group);
+
for (g = groups; g != NULL; g = g->fg_next)
- if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) &&
+ if ((strncmp(g->fg_name, gname, FR_GROUPLEN) == 0) &&
(g->fg_flags == (f->fr_flags & FR_INOUT)))
break;
@@ -190,7 +197,7 @@ frentry_t *fr;
g->fg_next = groups;
groups = g;
g->fg_head = f;
- bcopy(f->fr_group, g->fg_name, FR_GROUPLEN);
+ strncpy(g->fg_name, gname, FR_GROUPLEN);
g->fg_ref = 0;
g->fg_flags = f->fr_flags & FR_INOUT;
}
@@ -219,10 +226,10 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n",
g->fg_ref++;
- if (f->fr_grhead != 0) {
+ if (f->fr_grhead != -1) {
+ ghead = FR_NAME(f, fr_grhead);
for (g = groups; g != NULL; g = g->fg_next)
- if ((strncmp(g->fg_name, f->fr_grhead,
- FR_GROUPLEN) == 0) &&
+ if ((strncmp(g->fg_name, ghead, FR_GROUPLEN) == 0) &&
g->fg_flags == (f->fr_flags & FR_INOUT))
break;
if (g == NULL) {
@@ -230,7 +237,7 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n",
g->fg_next = groups;
groups = g;
g->fg_head = f;
- bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN);
+ strncpy(g->fg_name, ghead, FR_GROUPLEN);
g->fg_ref = 0;
g->fg_flags = f->fr_flags & FR_INOUT;
}
@@ -239,7 +246,7 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n",
int intcmp(c1, c2)
-const void *c1, *c2;
+ const void *c1, *c2;
{
const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2;
@@ -251,17 +258,17 @@ const void *c1, *c2;
static void indent(fp, in)
-FILE *fp;
-int in;
+ FILE *fp;
+ int in;
{
for (; in; in--)
fputc('\t', fp);
}
static void printeq(fp, var, m, max, v)
-FILE *fp;
-char *var;
-int m, max, v;
+ FILE *fp;
+ char *var;
+ int m, max, v;
{
if (m == max)
fprintf(fp, "%s == %#x) {\n", var, v);
@@ -276,9 +283,9 @@ int m, max, v;
* v - required address
*/
static void printipeq(fp, var, fl, m, v)
-FILE *fp;
-char *var;
-int fl, m, v;
+ FILE *fp;
+ char *var;
+ int fl, m, v;
{
if (m == 0xffffffff)
fprintf(fp, "%s ", var);
@@ -290,9 +297,9 @@ int fl, m, v;
void emit(num, dir, v, fr)
-int num, dir;
-void *v;
-frentry_t *fr;
+ int num, dir;
+ void *v;
+ frentry_t *fr;
{
u_int incnt, outcnt;
frgroup_t *g;
@@ -342,8 +349,8 @@ frentry_t *fr;
static void emitheader(grp, incount, outcount)
-frgroup_t *grp;
-u_int incount, outcount;
+ frgroup_t *grp;
+ u_int incount, outcount;
{
static FILE *fph = NULL;
frgroup_t *g;
@@ -434,11 +441,11 @@ int ipfrule_remove()\n\
static void emitGroup(num, dir, v, fr, group, incount, outcount)
-int num, dir;
-void *v;
-frentry_t *fr;
-char *group;
-u_int incount, outcount;
+ int num, dir;
+ void *v;
+ frentry_t *fr;
+ char *group;
+ u_int incount, outcount;
{
static FILE *fp = NULL;
static int header[2] = { 0, 0 };
@@ -514,9 +521,8 @@ u_int incount, outcount;
if ((i & 1) == 0) {
fprintf(fp, "\n\t");
}
- fprintf(fp,
- "(frentry_t *)&in_rule_%s_%d",
- f->fr_group, i);
+ fprintf(fp, "(frentry_t *)&in_rule_%s_%d",
+ FR_NAME(f, fr_group), i);
if (i + 1 < incount)
fprintf(fp, ", ");
i++;
@@ -534,9 +540,8 @@ u_int incount, outcount;
if ((i & 1) == 0) {
fprintf(fp, "\n\t");
}
- fprintf(fp,
- "(frentry_t *)&out_rule_%s_%d",
- f->fr_group, i);
+ fprintf(fp, "(frentry_t *)&out_rule_%s_%d",
+ FR_NAME(f, fr_group), i);
if (i + 1 < outcount)
fprintf(fp, ", ");
i++;
@@ -586,7 +591,7 @@ u_int incount, outcount;
switch(m[i].c)
{
case FRC_IFN :
- if (*fr->fr_ifname)
+ if (fr->fr_ifnames[0] != -1)
m[i].s = 1;
break;
case FRC_V :
@@ -940,11 +945,11 @@ u_int incount, outcount;
if (fr->fr_flags & FR_QUICK) {
fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n",
fr->fr_flags & FR_INQUE ? "in" : "out",
- fr->fr_group, num);
+ FR_NAME(fr, fr_group), num);
} else {
fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n",
fr->fr_flags & FR_INQUE ? "in" : "out",
- fr->fr_group, num);
+ FR_NAME(fr, fr_group), num);
}
if (n == NULL)
n = (mc_t *)malloc(sizeof(*n) * FRC_MAX);
@@ -954,7 +959,7 @@ u_int incount, outcount;
void printC(dir)
-int dir;
+ int dir;
{
static mc_t *m = NULL;
frgroup_t *g;
@@ -977,10 +982,10 @@ int dir;
* Now print out code to implement all of the rules.
*/
static void printCgroup(dir, top, m, group)
-int dir;
-frentry_t *top;
-mc_t *m;
-char *group;
+ int dir;
+ frentry_t *top;
+ mc_t *m;
+ char *group;
{
frentry_t *fr, *fr1;
int i, n, rn;
@@ -1027,13 +1032,14 @@ char *group;
continue;
if ((n & 0x0001) &&
- !strcmp(fr1->fr_ifname, fr->fr_ifname)) {
+ !strcmp(fr1->fr_names + fr1->fr_ifnames[0],
+ fr->fr_names + fr->fr_ifnames[0])) {
m[FRC_IFN].e++;
m[FRC_IFN].n++;
} else
n &= ~0x0001;
- if ((n & 0x0002) && (fr1->fr_v == fr->fr_v)) {
+ if ((n & 0x0002) && (fr1->fr_family == fr->fr_family)) {
m[FRC_V].e++;
m[FRC_V].n++;
} else
@@ -1226,10 +1232,10 @@ char *group;
}
static void printhooks(fp, in, out, grp)
-FILE *fp;
-int in;
-int out;
-frgroup_t *grp;
+ FILE *fp;
+ int in;
+ int out;
+ frgroup_t *grp;
{
frentry_t *fr;
char *group;
@@ -1237,7 +1243,7 @@ frgroup_t *grp;
char *instr;
group = grp->fg_name;
- dogrp = *group ? 1 : 0;
+ dogrp = 0;
if (in && out) {
fprintf(stderr,
@@ -1283,18 +1289,24 @@ int ipfrule_add_%s_%s()\n", instr, group);
fprintf(fp, "\
for (j = i + 1; j < max; j++)\n\
- if (strncmp(fp->fr_group,\n\
+ if (strncmp(fp->fr_names + fp->fr_group,\n\
+ ipf_rules_%s_%s[j]->fr_names +\n\
ipf_rules_%s_%s[j]->fr_group,\n\
FR_GROUPLEN) == 0) {\n\
+ if (ipf_rules_%s_%s[j] != NULL)\n\
+ ipf_rules_%s_%s[j]->fr_pnext =\n\
+ &fp->fr_next;\n\
+ fp->fr_pnext = &ipf_rules_%s_%s[j];\n\
fp->fr_next = ipf_rules_%s_%s[j];\n\
break;\n\
- }\n", instr, group, instr, group);
+ }\n", instr, group, instr, group, instr, group,
+ instr, group, instr, group, instr, group);
if (dogrp)
fprintf(fp, "\
\n\
- if (fp->fr_grhead != 0) {\n\
- fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\
- IPL_LOGIPF, 0);\n\
+ if (fp->fr_grhead != -1) {\n\
+ fg = fr_addgroup(fp->fr_names + fp->fr_grhead,\n\
+ fp, FR_INQUE, IPL_LOGIPF, 0);\n\
if (fg != NULL)\n\
fp->fr_grp = &fg->fg_start;\n\
}\n");
@@ -1304,7 +1316,7 @@ int ipfrule_add_%s_%s()\n", instr, group);
fp = &ipfrule_%s_%s;\n", instr, group);
fprintf(fp, "\
bzero((char *)fp, sizeof(*fp));\n\
- fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\
+ fp->fr_type = FR_T_CALLFUNC_BUILTIN;\n\
fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\
fp->fr_data = (void *)ipf_rules_%s_%s[0];\n",
(in != 0) ? "IN" : "OUT", instr, group);
@@ -1313,9 +1325,10 @@ int ipfrule_add_%s_%s()\n", instr, group);
instr, group);
fprintf(fp, "\
- fp->fr_v = 4;\n\
+ fp->fr_family = AF_INET;\n\
fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\
- err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n",
+ err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,\n\
+ ipfmain.ipf_active, 0);\n",
instr, group);
fprintf(fp, "\treturn err;\n}\n");
@@ -1348,8 +1361,9 @@ int ipfrule_remove_%s_%s()\n", instr, group);
}\n\
}\n\
if (err == 0)\n\
- err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\
- (caddr_t)&ipfrule_%s_%s, fr_active, 0);\n",
+ err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,\n\
+ (caddr_t)&ipfrule_%s_%s,\n\
+ ipfmain.ipf_active, 0);\n",
instr, group, instr, group, instr, group);
fprintf(fp, "\
if (err)\n\
diff --git a/contrib/ipfilter/tools/ipfs.c b/contrib/ipfilter/tools/ipfs.c
index eab650a7ee36..b5484be2193c 100644
--- a/contrib/ipfilter/tools/ipfs.c
+++ b/contrib/ipfilter/tools/ipfs.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -44,7 +44,7 @@
#include "netinet/ipl.h"
#if !defined(lint)
-static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp";
+static const char rcsid[] = "@(#)$Id$";
#endif
#ifndef IPF_SAVEDIR
@@ -100,7 +100,7 @@ void usage()
* Change interface names in state information saved out to disk.
*/
int changestateif(ifs, fname)
-char *ifs, *fname;
+ char *ifs, *fname;
{
int fd, olen, nlen, rw;
ipstate_save_t ips;
@@ -163,7 +163,7 @@ char *ifs, *fname;
* Change interface names in NAT information saved out to disk.
*/
int changenatif(ifs, fname)
-char *ifs, *fname;
+ char *ifs, *fname;
{
int fd, olen, nlen, rw;
nat_save_t ipn;
@@ -198,14 +198,6 @@ char *ifs, *fname;
strcpy(nat->nat_ifnames[1], s);
rw = 1;
}
- if (!strncmp(nat->nat_ifnames[2], ifs, olen + 1)) {
- strcpy(nat->nat_ifnames[2], s);
- rw = 1;
- }
- if (!strncmp(nat->nat_ifnames[3], ifs, olen + 1)) {
- strcpy(nat->nat_ifnames[3], s);
- rw = 1;
- }
if (rw == 1) {
if (lseek(fd, pos, SEEK_SET) != pos) {
perror("lseek");
@@ -225,8 +217,8 @@ char *ifs, *fname;
int main(argc,argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0;
char *dirname = NULL, *filename = NULL, *ifs = NULL;
@@ -356,7 +348,7 @@ char *argv[];
int opendevice(ipfdev)
-char *ipfdev;
+ char *ipfdev;
{
int fd = -1;
@@ -374,14 +366,14 @@ char *ipfdev;
void closedevice(fd)
-int fd;
+ int fd;
{
close(fd);
}
int setlock(fd, lock)
-int fd, lock;
+ int fd, lock;
{
if (opts & OPT_VERBOSE)
printf("Turn lock %s\n", lock ? "on" : "off");
@@ -398,8 +390,8 @@ int fd, lock;
int writestate(fd, file)
-int fd;
-char *file;
+ int fd;
+ char *file;
{
ipstate_save_t ips, *ipsp;
ipfobj_t obj;
@@ -450,8 +442,8 @@ char *file;
int readstate(fd, file)
-int fd;
-char *file;
+ int fd;
+ char *file;
{
ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL;
int sfd = -1, i;
@@ -567,8 +559,8 @@ freeipshead:
int readnat(fd, file)
-int fd;
-char *file;
+ int fd;
+ char *file;
{
nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL;
ipfobj_t obj;
@@ -714,8 +706,8 @@ freenathead:
int writenat(fd, file)
-int fd;
-char *file;
+ int fd;
+ char *file;
{
nat_save_t *ipnp = NULL, *next = NULL;
ipfobj_t obj;
@@ -798,7 +790,7 @@ char *file;
int writeall(dirname)
-char *dirname;
+ char *dirname;
{
int fd, devfd;
@@ -849,7 +841,7 @@ bad:
int readall(dirname)
-char *dirname;
+ char *dirname;
{
int fd, devfd;
diff --git a/contrib/ipfilter/tools/ipfstat.c b/contrib/ipfilter/tools/ipfstat.c
index 3c5bfdd50ac4..3261cef8e4d2 100644
--- a/contrib/ipfilter/tools/ipfstat.c
+++ b/contrib/ipfilter/tools/ipfstat.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2002-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -15,6 +15,7 @@
# endif
#endif
#include <sys/ioctl.h>
+#include <ctype.h>
#include <fcntl.h>
#ifdef linux
# include <linux/a.out.h>
@@ -71,7 +72,7 @@
#if !defined(lint)
static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.44.2.25 2007/06/30 09:48:50 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
#ifdef __hpux
@@ -87,7 +88,9 @@ extern int opterr;
static char *filters[4] = { "ipfilter(in)", "ipfilter(out)",
"ipacct(in)", "ipacct(out)" };
static int state_logging = -1;
+static wordtab_t *state_fields = NULL;
+int nohdrfields = 0;
int opts = 0;
int use_inet6 = 0;
int live_kernel = 1;
@@ -98,6 +101,26 @@ int nat_fd = -1;
frgroup_t *grtop = NULL;
frgroup_t *grtail = NULL;
+char *blockreasons[FRB_MAX_VALUE + 1] = {
+ "packet blocked",
+ "log rule failure",
+ "pps rate exceeded",
+ "jumbogram",
+ "makefrip failed",
+ "cannot add state",
+ "IP ID update failed",
+ "log-or-block failed",
+ "decapsulate failure",
+ "cannot create new auth entry",
+ "packet queued for auth",
+ "buffer coalesce failure",
+ "buffer pullup failure",
+ "auth feedback",
+ "bad fragment",
+ "IPv4 NAT failure",
+ "IPv6 NAT failure"
+};
+
#ifdef STATETOP
#define STSTRSIZE 80
#define STGROWSIZE 16
@@ -135,22 +158,27 @@ static int fetchfrag __P((int, int, ipfr_t *));
static void showstats __P((friostat_t *, u_32_t));
static void showfrstates __P((ipfrstat_t *, u_long));
static void showlist __P((friostat_t *));
-static void showipstates __P((ips_stat_t *));
-static void showauthstates __P((fr_authstat_t *));
+static void showstatestats __P((ips_stat_t *));
+static void showipstates __P((ips_stat_t *, int *));
+static void showauthstates __P((ipf_authstat_t *));
+static void showtqtable_live __P((int));
static void showgroups __P((friostat_t *));
static void usage __P((char *));
-static void showtqtable_live __P((int));
-static void printlivelist __P((int, int, frentry_t *, char *, char *));
-static void printdeadlist __P((int, int, frentry_t *, char *, char *));
+static int state_matcharray __P((ipstate_t *, int *));
+static int printlivelist __P((friostat_t *, int, int, frentry_t *,
+ char *, char *));
+static void printdeadlist __P((friostat_t *, int, int, frentry_t *,
+ char *, char *));
+static void printside __P((char *, ipf_statistics_t *));
static void parse_ipportstr __P((const char *, i6addr_t *, int *));
static void ipfstate_live __P((char *, friostat_t **, ips_stat_t **,
- ipfrstat_t **, fr_authstat_t **, u_32_t *));
+ ipfrstat_t **, ipf_authstat_t **, u_32_t *));
static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **,
- ipfrstat_t **, fr_authstat_t **, u_32_t *));
+ ipfrstat_t **, ipf_authstat_t **, u_32_t *));
static ipstate_t *fetchstate __P((ipstate_t *, ipstate_t *));
#ifdef STATETOP
static void topipstates __P((i6addr_t, i6addr_t, int, int, int,
- int, int, int));
+ int, int, int, int *));
static void sig_break __P((int));
static void sig_resize __P((int));
static char *getip __P((int, i6addr_t *));
@@ -167,7 +195,7 @@ static int sort_dstpt __P((const void *, const void *));
static void usage(name)
-char *name;
+ char *name;
{
#ifdef USE_INET6
fprintf(stderr, "Usage: %s [-6aAdfghIilnoRsv]\n", name);
@@ -186,20 +214,23 @@ char *name;
int main(argc,argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
- fr_authstat_t frauthst;
- fr_authstat_t *frauthstp = &frauthst;
+ ipf_authstat_t frauthst;
+ ipf_authstat_t *frauthstp = &frauthst;
friostat_t fio;
friostat_t *fiop = &fio;
ips_stat_t ipsst;
ips_stat_t *ipsstp = &ipsst;
ipfrstat_t ifrst;
ipfrstat_t *ifrstp = &ifrst;
- char *memf = NULL;
- char *options, *kern = NULL;
- int c, myoptind;
+ char *options;
+ char *kern = NULL;
+ char *memf = NULL;
+ int c;
+ int myoptind;
+ int *filter = NULL;
int protocol = -1; /* -1 = wild card for any protocol */
int refreshtime = 1; /* default update time */
@@ -210,9 +241,9 @@ char *argv[];
u_32_t frf;
#ifdef USE_INET6
- options = "6aACdfghIilnostvD:M:N:P:RS:T:";
+ options = "6aACdfghIilnostvD:m:M:N:O:P:RS:T:";
#else
- options = "aACdfghIilnostvD:M:N:P:RS:T:";
+ options = "aACdfghIilnostvD:m:M:N:O:P:RS:T:";
#endif
saddr.in4.s_addr = INADDR_ANY; /* default any v4 source addr */
@@ -324,6 +355,14 @@ char *argv[];
case 'l' :
opts |= OPT_SHOWLIST;
break;
+ case 'm' :
+ filter = parseipfexpr(optarg, NULL);
+ if (filter == NULL) {
+ fprintf(stderr, "Error parseing '%s'\n",
+ optarg);
+ exit(1);
+ }
+ break;
case 'M' :
break;
case 'N' :
@@ -334,6 +373,9 @@ char *argv[];
case 'o' :
opts |= OPT_OUTQUE|OPT_SHOWLIST;
break;
+ case 'O' :
+ state_fields = parsefields(statefields, optarg);
+ break;
case 'P' :
protocol = getproto(optarg);
if (protocol == -1) {
@@ -386,11 +428,12 @@ char *argv[];
ipfstate_live(IPL_NAME, &fiop, &ipsstp, &ifrstp,
&frauthstp, &frf);
- } else
+ } else {
ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf);
+ }
if (opts & OPT_IPSTATES) {
- showipstates(ipsstp);
+ showipstates(ipsstp, filter);
} else if (opts & OPT_SHOWLIST) {
showlist(fiop);
if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
@@ -402,7 +445,7 @@ char *argv[];
#ifdef STATETOP
else if (opts & OPT_STATETOP)
topipstates(saddr, daddr, sport, dport, protocol,
- use_inet6 ? 6 : 4, refreshtime, topclosed);
+ use_inet6 ? 6 : 4, refreshtime, topclosed, filter);
#endif
else if (opts & OPT_AUTHSTATS)
showauthstates(frauthstp);
@@ -420,12 +463,12 @@ char *argv[];
* of ioctl's and copying directly from kernel memory.
*/
static void ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
-char *device;
-friostat_t **fiopp;
-ips_stat_t **ipsstpp;
-ipfrstat_t **ifrstpp;
-fr_authstat_t **frauthstpp;
-u_32_t *frfp;
+ char *device;
+ friostat_t **fiopp;
+ ips_stat_t **ipsstpp;
+ ipfrstat_t **ifrstpp;
+ ipf_authstat_t **frauthstpp;
+ u_32_t *frfp;
{
ipfobj_t ipfo;
@@ -442,12 +485,12 @@ u_32_t *frfp;
ipfo.ipfo_ptr = (void *)*fiopp;
if (ioctl(ipf_fd, SIOCGETFS, &ipfo) == -1) {
- perror("ioctl(ipf:SIOCGETFS)");
+ ipferror(ipf_fd, "ioctl(ipf:SIOCGETFS)");
exit(-1);
}
if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1)
- perror("ioctl(SIOCGETFF)");
+ ipferror(ipf_fd, "ioctl(SIOCGETFF)");
}
if ((opts & OPT_IPSTATES) != 0) {
@@ -459,11 +502,11 @@ u_32_t *frfp;
ipfo.ipfo_ptr = (void *)*ipsstpp;
if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) {
- perror("ioctl(state:SIOCGETFS)");
+ ipferror(state_fd, "ioctl(state:SIOCGETFS)");
exit(-1);
}
if (ioctl(state_fd, SIOCGETLG, &state_logging) == -1) {
- perror("ioctl(state:SIOCGETLG)");
+ ipferror(state_fd, "ioctl(state:SIOCGETLG)");
exit(-1);
}
}
@@ -474,9 +517,9 @@ u_32_t *frfp;
ipfo.ipfo_type = IPFOBJ_FRAGSTAT;
ipfo.ipfo_size = sizeof(ipfrstat_t);
ipfo.ipfo_ptr = (void *)*ifrstpp;
-
+
if (ioctl(ipf_fd, SIOCGFRST, &ipfo) == -1) {
- perror("ioctl(SIOCGFRST)");
+ ipferror(ipf_fd, "ioctl(SIOCGFRST)");
exit(-1);
}
}
@@ -488,11 +531,11 @@ u_32_t *frfp;
bzero((caddr_t)&ipfo, sizeof(ipfo));
ipfo.ipfo_rev = IPFILTER_VERSION;
ipfo.ipfo_type = IPFOBJ_AUTHSTAT;
- ipfo.ipfo_size = sizeof(fr_authstat_t);
+ ipfo.ipfo_size = sizeof(ipf_authstat_t);
ipfo.ipfo_ptr = (void *)*frauthstpp;
if (ioctl(auth_fd, SIOCATHST, &ipfo) == -1) {
- perror("ioctl(SIOCATHST)");
+ ipferror(auth_fd, "ioctl(SIOCATHST)");
exit(-1);
}
}
@@ -505,66 +548,64 @@ u_32_t *frfp;
* just won't work any more.
*/
static void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp)
-char *kernel;
-friostat_t **fiopp;
-ips_stat_t **ipsstpp;
-ipfrstat_t **ifrstpp;
-fr_authstat_t **frauthstpp;
-u_32_t *frfp;
+ char *kernel;
+ friostat_t **fiopp;
+ ips_stat_t **ipsstpp;
+ ipfrstat_t **ifrstpp;
+ ipf_authstat_t **frauthstpp;
+ u_32_t *frfp;
{
- static fr_authstat_t frauthst, *frauthstp;
+ static ipf_authstat_t frauthst, *frauthstp;
+ static ipftq_t ipstcptab[IPF_TCP_NSTATES];
static ips_stat_t ipsst, *ipsstp;
static ipfrstat_t ifrst, *ifrstp;
static friostat_t fio, *fiop;
- static ipftq_t ipssttab[IPF_TCP_NSTATES];
int temp;
void *rules[2][2];
struct nlist deadlist[44] = {
- { "fr_authstats" }, /* 0 */
- { "fae_list" },
- { "ipauth" },
- { "fr_authlist" },
- { "fr_authstart" },
- { "fr_authend" }, /* 5 */
- { "fr_authnext" },
- { "fr_auth" },
- { "fr_authused" },
- { "fr_authsize" },
- { "fr_defaultauthage" }, /* 10 */
- { "fr_authpkts" },
- { "fr_auth_lock" },
- { "frstats" },
- { "ips_stats" },
- { "ips_num" }, /* 15 */
- { "ips_wild" },
- { "ips_list" },
- { "ips_table" },
- { "fr_statemax" },
- { "fr_statesize" }, /* 20 */
- { "fr_state_doflush" },
- { "fr_state_lock" },
- { "ipfr_heads" },
- { "ipfr_nattab" },
- { "ipfr_stats" }, /* 25 */
- { "ipfr_inuse" },
- { "fr_ipfrttl" },
- { "fr_frag_lock" },
- { "ipfr_timer_id" },
- { "fr_nat_lock" }, /* 30 */
- { "ipfilter" },
- { "ipfilter6" },
- { "ipacct" },
- { "ipacct6" },
- { "ipl_frouteok" }, /* 35 */
- { "fr_running" },
- { "ipfgroups" },
- { "fr_active" },
- { "fr_pass" },
- { "fr_flags" }, /* 40 */
- { "ipstate_logging" },
- { "ips_tqtqb" },
- { NULL }
+ { "ipf_auth_stats", 0, 0, 0, 0 }, /* 0 */
+ { "fae_list", 0, 0, 0, 0 },
+ { "ipauth", 0, 0, 0, 0 },
+ { "ipf_auth_list", 0, 0, 0, 0 },
+ { "ipf_auth_start", 0, 0, 0, 0 },
+ { "ipf_auth_end", 0, 0, 0, 0 }, /* 5 */
+ { "ipf_auth_next", 0, 0, 0, 0 },
+ { "ipf_auth", 0, 0, 0, 0 },
+ { "ipf_auth_used", 0, 0, 0, 0 },
+ { "ipf_auth_size", 0, 0, 0, 0 },
+ { "ipf_auth_defaultage", 0, 0, 0, 0 }, /* 10 */
+ { "ipf_auth_pkts", 0, 0, 0, 0 },
+ { "ipf_auth_lock", 0, 0, 0, 0 },
+ { "frstats", 0, 0, 0, 0 },
+ { "ips_stats", 0, 0, 0, 0 },
+ { "ips_num", 0, 0, 0, 0 }, /* 15 */
+ { "ips_wild", 0, 0, 0, 0 },
+ { "ips_list", 0, 0, 0, 0 },
+ { "ips_table", 0, 0, 0, 0 },
+ { "ipf_state_max", 0, 0, 0, 0 },
+ { "ipf_state_size", 0, 0, 0, 0 }, /* 20 */
+ { "ipf_state_doflush", 0, 0, 0, 0 },
+ { "ipf_state_lock", 0, 0, 0, 0 },
+ { "ipfr_heads", 0, 0, 0, 0 },
+ { "ipfr_nattab", 0, 0, 0, 0 },
+ { "ipfr_stats", 0, 0, 0, 0 }, /* 25 */
+ { "ipfr_inuse", 0, 0, 0, 0 },
+ { "ipf_ipfrttl", 0, 0, 0, 0 },
+ { "ipf_frag_lock", 0, 0, 0, 0 },
+ { "ipfr_timer_id", 0, 0, 0, 0 },
+ { "ipf_nat_lock", 0, 0, 0, 0 }, /* 30 */
+ { "ipf_rules", 0, 0, 0, 0 },
+ { "ipf_acct", 0, 0, 0, 0 },
+ { "ipl_frouteok", 0, 0, 0, 0 },
+ { "ipf_running", 0, 0, 0, 0 },
+ { "ipf_groups", 0, 0, 0, 0 }, /* 35 */
+ { "ipf_active", 0, 0, 0, 0 },
+ { "ipf_pass", 0, 0, 0, 0 },
+ { "ipf_flags", 0, 0, 0, 0 },
+ { "ipf_state_logging", 0, 0, 0, 0 },
+ { "ips_tqtqb", 0, 0, 0, 0 }, /* 40 */
+ { NULL, 0, 0, 0, 0 }
};
@@ -618,23 +659,6 @@ u_32_t *frfp;
fiop->f_fout[1] = rules[1][1];
/*
- * Same for IPv6, except make them null if support for it is not
- * being compiled in.
- */
-#ifdef USE_INET6
- kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules));
- fiop->f_fin6[0] = rules[0][0];
- fiop->f_fin6[1] = rules[0][1];
- fiop->f_fout6[0] = rules[1][0];
- fiop->f_fout6[1] = rules[1][1];
-#else
- fiop->f_fin6[0] = NULL;
- fiop->f_fin6[1] = NULL;
- fiop->f_fout6[0] = NULL;
- fiop->f_fout6[1] = NULL;
-#endif
-
- /*
* Now get accounting rules pointers.
*/
kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules));
@@ -643,32 +667,19 @@ u_32_t *frfp;
fiop->f_acctout[0] = rules[1][0];
fiop->f_acctout[1] = rules[1][1];
-#ifdef USE_INET6
- kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules));
- fiop->f_acctin6[0] = rules[0][0];
- fiop->f_acctin6[1] = rules[0][1];
- fiop->f_acctout6[0] = rules[1][0];
- fiop->f_acctout6[1] = rules[1][1];
-#else
- fiop->f_acctin6[0] = NULL;
- fiop->f_acctin6[1] = NULL;
- fiop->f_acctout6[0] = NULL;
- fiop->f_acctout6[1] = NULL;
-#endif
-
/*
* A collection of "global" variables used inside the kernel which
* are all collected in friostat_t via ioctl.
*/
- kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value,
+ kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[33].n_value,
sizeof(fiop->f_froute));
- kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value,
+ kmemcpy((char *)&fiop->f_running, (u_long)deadlist[34].n_value,
sizeof(fiop->f_running));
- kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value,
+ kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[35].n_value,
sizeof(fiop->f_groups));
- kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value,
+ kmemcpy((char *)&fiop->f_active, (u_long)deadlist[36].n_value,
sizeof(fiop->f_active));
- kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value,
+ kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[37].n_value,
sizeof(fiop->f_defpass));
/*
@@ -676,12 +687,12 @@ u_32_t *frfp;
*/
kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp));
kmemcpy((char *)&temp, (u_long)deadlist[15].n_value, sizeof(temp));
- kmemcpy((char *)ipssttab, (u_long)deadlist[42].n_value,
- sizeof(ipssttab));
+ kmemcpy((char *)ipstcptab, (u_long)deadlist[40].n_value,
+ sizeof(ipstcptab));
ipsstp->iss_active = temp;
ipsstp->iss_table = (void *)deadlist[18].n_value;
ipsstp->iss_list = (void *)deadlist[17].n_value;
- ipsstp->iss_tcptab = ipssttab;
+ ipsstp->iss_tcptab = ipstcptab;
/*
* Build up the authentiation information stats structure.
@@ -708,65 +719,62 @@ u_32_t *frfp;
}
+static void printside(side, frs)
+ char *side;
+ ipf_statistics_t *frs;
+{
+ int i;
+
+ PRINTF("%lu\t%s bad packets\n", frs->fr_bad, side);
+#ifdef USE_INET6
+ PRINTF("%lu\t%s IPv6 packets\n", frs->fr_ipv6, side);
+#endif
+ PRINTF("%lu\t%s packets blocked\n", frs->fr_block, side);
+ PRINTF("%lu\t%s packets passed\n", frs->fr_pass, side);
+ PRINTF("%lu\t%s packets not matched\n", frs->fr_nom, side);
+ PRINTF("%lu\t%s packets counted\n", frs->fr_acct, side);
+ PRINTF("%lu\t%s packets short\n", frs->fr_short, side);
+ PRINTF("%lu\t%s packets logged and blocked\n", frs->fr_bpkl, side);
+ PRINTF("%lu\t%s packets logged and passed\n", frs->fr_ppkl, side);
+ PRINTF("%lu\t%s fragment state kept\n", frs->fr_nfr, side);
+ PRINTF("%lu\t%s fragment state lost\n", frs->fr_bnfr, side);
+ PRINTF("%lu\t%s packet state kept\n", frs->fr_ads, side);
+ PRINTF("%lu\t%s packet state lost\n", frs->fr_bads, side);
+ PRINTF("%lu\t%s invalid source\n", frs->fr_v4_badsrc, side);
+ PRINTF("%lu\t%s cache hits\n", frs->fr_chit, side);
+ PRINTF("%lu\t%s cache misses\n", frs->fr_cmiss, side);
+ PRINTF("%lu\t%s bad coalesces\n", frs->fr_badcoalesces, side);
+ PRINTF("%lu\t%s pullups succeeded\n", frs->fr_pull[0], side);
+ PRINTF("%lu\t%s pullups failed\n", frs->fr_pull[1], side);
+ PRINTF("%lu\t%s TCP checksum failures\n", frs->fr_tcpbad, side);
+ for (i = 0; i <= FRB_MAX_VALUE; i++)
+ PRINTF("%lu\t%s block reason %s\n",
+ frs->fr_blocked[i], side, blockreasons[i]);
+}
+
+
/*
* Display the kernel stats for packets blocked and passed and other
* associated running totals which are kept.
*/
static void showstats(fp, frf)
-struct friostat *fp;
-u_32_t frf;
+ struct friostat *fp;
+ u_32_t frf;
{
+ printside("input", &fp->f_st[0]);
+ printside("output", &fp->f_st[1]);
- PRINTF("bad packets:\t\tin %lu\tout %lu\n",
- fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
-#ifdef USE_INET6
- PRINTF(" IPv6 packets:\t\tin %lu out %lu\n",
- fp->f_st[0].fr_ipv6, fp->f_st[1].fr_ipv6);
-#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 short %lu\n",
- fp->f_st[0].fr_acct, fp->f_st[0].fr_short);
- 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 short %lu\n",
- fp->f_st[1].fr_acct, fp->f_st[1].fr_short);
- 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 output %lu\n",
- fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl);
- PRINTF(" log failures:\t\tinput %lu output %lu\n",
- fp->f_st[0].fr_skip, fp->f_st[1].fr_skip);
- PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n",
- fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr,
- fp->f_st[0].fr_cfr);
- PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n",
- fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr,
- fp->f_st[0].fr_cfr);
- PRINTF("packet state(in):\tkept %lu\tlost %lu\n",
- fp->f_st[0].fr_ads, fp->f_st[0].fr_bads);
- PRINTF("packet state(out):\tkept %lu\tlost %lu\n",
- fp->f_st[1].fr_ads, fp->f_st[1].fr_bads);
- PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n",
- fp->f_st[0].fr_ret, fp->f_st[1].fr_ret);
- PRINTF("Invalid source(in):\t%lu\n", fp->f_st[0].fr_badsrc);
- PRINTF("Result cache hits(in):\t%lu\t(out):\t%lu\n",
- fp->f_st[0].fr_chit, fp->f_st[1].fr_chit);
- PRINTF("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n",
- fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]);
- PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n",
- fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]);
- PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n",
- fp->f_froute[0], fp->f_froute[1]);
- PRINTF("TCP cksum fails(in):\t%lu\t(out):\t%lu\n",
- fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad);
- PRINTF("IPF Ticks:\t%lu\n", fp->f_ticks);
+ PRINTF("%lu\tpackets logged\n", fp->f_log_ok);
+ PRINTF("%lu\tlog failures\n", fp->f_log_fail);
+ PRINTF("%lu\tred-black no memory\n", fp->f_rb_no_mem);
+ PRINTF("%lu\tred-black node maximum\n", fp->f_rb_node_max);
+ PRINTF("%lu\tICMP replies sent\n", fp->f_st[0].fr_ret);
+ PRINTF("%lu\tTCP RSTs sent\n", fp->f_st[1].fr_ret);
+ PRINTF("%lu\tfastroute successes\n", fp->f_froute[0]);
+ PRINTF("%lu\tfastroute failures\n", fp->f_froute[1]);
+ PRINTF("%u\tIPF Ticks\n", fp->f_ticks);
- PRINTF("Packet log flags set: (%#x)\n", frf);
+ PRINTF("%x\tPacket log flags set:\n", frf);
if (frf & FF_LOGPASS)
PRINTF("\tpackets passed through filter\n");
if (frf & FF_LOGBLOCK)
@@ -781,30 +789,27 @@ u_32_t frf;
/*
* Print out a list of rules from the kernel, starting at the one passed.
*/
-static void printlivelist(out, set, fp, group, comment)
-int out, set;
-frentry_t *fp;
-char *group, *comment;
+static int
+printlivelist(fiop, out, set, fp, group, comment)
+ struct friostat *fiop;
+ int out, set;
+ frentry_t *fp;
+ char *group, *comment;
{
struct frentry fb;
ipfruleiter_t rule;
frentry_t zero;
frgroup_t *g;
ipfobj_t obj;
- int n;
+ int rules;
+ int num;
- if (use_inet6 == 1)
- fb.fr_v = 6;
- else
- fb.fr_v = 4;
- fb.fr_next = fp;
- n = 0;
+ rules = 0;
rule.iri_inout = out;
rule.iri_active = set;
rule.iri_rule = &fb;
rule.iri_nrules = 1;
- rule.iri_v = use_inet6 ? 6 : 4;
if (group != NULL)
strncpy(rule.iri_group, group, FR_GROUPLEN);
else
@@ -818,49 +823,65 @@ char *group, *comment;
obj.ipfo_size = sizeof(rule);
obj.ipfo_ptr = &rule;
- do {
+ while (rule.iri_rule != NULL) {
u_long array[1000];
memset(array, 0xff, sizeof(array));
fp = (frentry_t *)array;
rule.iri_rule = fp;
if (ioctl(ipf_fd, SIOCIPFITER, &obj) == -1) {
- perror("ioctl(SIOCIPFITER)");
- n = IPFGENITER_IPF;
- ioctl(ipf_fd, SIOCIPFDELTOK, &n);
- return;
+ ipferror(ipf_fd, "ioctl(SIOCIPFITER)");
+ num = IPFGENITER_IPF;
+ (void) ioctl(ipf_fd,SIOCIPFDELTOK, &num);
+ return rules;
}
if (bcmp(fp, &zero, sizeof(zero)) == 0)
break;
+ if (rule.iri_rule == NULL)
+ break;
+#ifdef USE_INET6
+ if (use_inet6 != 0) {
+ if (fp->fr_family != 0 && fp->fr_family != AF_INET6)
+ continue;
+ } else
+#endif
+ {
+ if (fp->fr_family != 0 && fp->fr_family != AF_INET)
+ continue;
+ }
if (fp->fr_data != NULL)
- fp->fr_data = (char *)fp + sizeof(*fp);
+ fp->fr_data = (char *)fp + fp->fr_size;
- n++;
+ rules++;
- if (opts & (OPT_HITS|OPT_VERBOSE))
+ if (opts & (OPT_HITS|OPT_DEBUG))
#ifdef USE_QUAD_T
- PRINTF("%qu ", (unsigned long long) fp->fr_hits);
+ PRINTF("%"PRIu64" ", (unsigned long long) fp->fr_hits);
#else
PRINTF("%lu ", fp->fr_hits);
#endif
- if (opts & (OPT_ACCNT|OPT_VERBOSE))
+ if (opts & (OPT_ACCNT|OPT_DEBUG))
#ifdef USE_QUAD_T
- PRINTF("%qu ", (unsigned long long) fp->fr_bytes);
+ PRINTF("%"PRIu64" ", (unsigned long long) fp->fr_bytes);
#else
PRINTF("%lu ", fp->fr_bytes);
#endif
if (opts & OPT_SHOWLINENO)
- PRINTF("@%d ", n);
+ PRINTF("@%d ", rules);
+
+ if (fp->fr_die != 0)
+ fp->fr_die -= fiop->f_ticks;
printfr(fp, ioctl);
if (opts & OPT_DEBUG) {
- binprint(fp, sizeof(*fp));
+ binprint(fp, fp->fr_size);
if (fp->fr_data != NULL && fp->fr_dsize > 0)
binprint(fp->fr_data, fp->fr_dsize);
}
- if (fp->fr_grhead[0] != '\0') {
+ if (fp->fr_grhead != -1) {
for (g = grtop; g != NULL; g = g->fg_next) {
- if (!strncmp(fp->fr_grhead, g->fg_name,
+ if (!strncmp(fp->fr_names + fp->fr_grhead,
+ g->fg_name,
FR_GROUPLEN))
break;
}
@@ -868,7 +889,8 @@ char *group, *comment;
g = calloc(1, sizeof(*g));
if (g != NULL) {
- strncpy(g->fg_name, fp->fr_grhead,
+ strncpy(g->fg_name,
+ fp->fr_names + fp->fr_grhead,
FR_GROUPLEN);
if (grtop == NULL) {
grtop = g;
@@ -881,29 +903,23 @@ char *group, *comment;
}
}
if (fp->fr_type == FR_T_CALLFUNC) {
- printlivelist(out, set, fp->fr_data, group,
- "# callfunc: ");
+ rules += printlivelist(fiop, out, set, fp->fr_data,
+ group, "# callfunc: ");
}
- } while (fp->fr_next != NULL);
+ }
- n = IPFGENITER_IPF;
- ioctl(ipf_fd, SIOCIPFDELTOK, &n);
+ num = IPFGENITER_IPF;
+ (void) ioctl(ipf_fd,SIOCIPFDELTOK, &num);
- if (group == NULL) {
- while ((g = grtop) != NULL) {
- printf("# Group %s\n", g->fg_name);
- printlivelist(out, set, NULL, g->fg_name, comment);
- grtop = g->fg_next;
- free(g);
- }
- }
+ return rules;
}
-static void printdeadlist(out, set, fp, group, comment)
-int out, set;
-frentry_t *fp;
-char *group, *comment;
+static void printdeadlist(fiop, out, set, fp, group, comment)
+ friostat_t *fiop;
+ int out, set;
+ frentry_t *fp;
+ char *group, *comment;
{
frgroup_t *grtop, *grtail, *g;
struct frentry fb;
@@ -916,13 +932,20 @@ char *group, *comment;
grtop = NULL;
grtail = NULL;
- do {
- fp = fb.fr_next;
+ for (n = 1; fp; fp = fb.fr_next, n++) {
if (kmemcpy((char *)&fb, (u_long)fb.fr_next,
- sizeof(fb)) == -1) {
+ fb.fr_size) == -1) {
perror("kmemcpy");
return;
}
+ fp = &fb;
+ if (use_inet6 != 0) {
+ if (fp->fr_family != 0 && fp->fr_family != 6)
+ continue;
+ } else {
+ if (fp->fr_family != 0 && fp->fr_family != 4)
+ continue;
+ }
data = NULL;
type = fb.fr_type & ~FR_T_BUILTIN;
@@ -939,17 +962,15 @@ char *group, *comment;
}
}
- n++;
-
- if (opts & (OPT_HITS|OPT_VERBOSE))
+ if (opts & OPT_HITS)
#ifdef USE_QUAD_T
- PRINTF("%qu ", (unsigned long long) fb.fr_hits);
+ PRINTF("%"PRIu64" ", (unsigned long long) fb.fr_hits);
#else
PRINTF("%lu ", fb.fr_hits);
#endif
- if (opts & (OPT_ACCNT|OPT_VERBOSE))
+ if (opts & OPT_ACCNT)
#ifdef USE_QUAD_T
- PRINTF("%qu ", (unsigned long long) fb.fr_bytes);
+ PRINTF("%"PRIu64" ", (unsigned long long) fb.fr_bytes);
#else
PRINTF("%lu ", fb.fr_bytes);
#endif
@@ -958,17 +979,17 @@ char *group, *comment;
printfr(fp, ioctl);
if (opts & OPT_DEBUG) {
- binprint(fp, sizeof(*fp));
+ binprint(fp, fp->fr_size);
if (fb.fr_data != NULL && fb.fr_dsize > 0)
binprint(fb.fr_data, fb.fr_dsize);
}
if (data != NULL)
free(data);
- if (fb.fr_grhead[0] != '\0') {
+ if (fb.fr_grhead != -1) {
g = calloc(1, sizeof(*g));
if (g != NULL) {
- strncpy(g->fg_name, fb.fr_grhead,
+ strncpy(g->fg_name, fb.fr_names + fb.fr_grhead,
FR_GROUPLEN);
if (grtop == NULL) {
grtop = g;
@@ -980,13 +1001,13 @@ char *group, *comment;
}
}
if (type == FR_T_CALLFUNC) {
- printdeadlist(out, set, fb.fr_data, group,
+ printdeadlist(fiop, out, set, fb.fr_data, group,
"# callfunc: ");
}
- } while (fb.fr_next != NULL);
+ }
while ((g = grtop) != NULL) {
- printdeadlist(out, set, NULL, g->fg_name, comment);
+ printdeadlist(fiop, out, set, NULL, g->fg_name, comment);
grtop = g->fg_next;
free(g);
}
@@ -997,7 +1018,7 @@ char *group, *comment;
* the base from which to get the pointers.
*/
static void showlist(fiop)
-struct friostat *fiop;
+ struct friostat *fiop;
{
struct frentry *fp = NULL;
int i, set;
@@ -1006,15 +1027,6 @@ struct friostat *fiop;
if (opts & OPT_INACTIVE)
set = 1 - set;
if (opts & OPT_ACCNT) {
-#ifdef USE_INET6
- if ((use_inet6) && (opts & OPT_OUTQUE)) {
- i = F_ACOUT;
- fp = (struct frentry *)fiop->f_acctout6[set];
- } else if ((use_inet6) && (opts & OPT_INQUE)) {
- i = F_ACIN;
- fp = (struct frentry *)fiop->f_acctin6[set];
- } else
-#endif
if (opts & OPT_OUTQUE) {
i = F_ACOUT;
fp = (struct frentry *)fiop->f_acctout[set];
@@ -1026,15 +1038,6 @@ struct friostat *fiop;
return;
}
} else {
-#ifdef USE_INET6
- if ((use_inet6) && (opts & OPT_OUTQUE)) {
- i = F_OUT;
- fp = (struct frentry *)fiop->f_fout6[set];
- } else if ((use_inet6) && (opts & OPT_INQUE)) {
- i = F_IN;
- fp = (struct frentry *)fiop->f_fin6[set];
- } else
-#endif
if (opts & OPT_OUTQUE) {
i = F_OUT;
fp = (struct frentry *)fiop->f_fout[set];
@@ -1049,139 +1052,243 @@ struct friostat *fiop;
if (opts & OPT_DEBUG)
PRINTF("fp %p set %d\n", fp, set);
- if (!fp) {
- FPRINTF(stderr, "empty list for %s%s\n",
- (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]);
- return;
+
+ if (live_kernel == 1) {
+ int printed;
+
+ printed = printlivelist(fiop, i, set, fp, NULL, NULL);
+ if (printed == 0) {
+ FPRINTF(stderr, "# empty list for %s%s\n",
+ (opts & OPT_INACTIVE) ? "inactive " : "",
+ filters[i]);
+ }
+ } else {
+ if (!fp) {
+ FPRINTF(stderr, "# empty list for %s%s\n",
+ (opts & OPT_INACTIVE) ? "inactive " : "",
+ filters[i]);
+ } else {
+ printdeadlist(fiop, i, set, fp, NULL, NULL);
+ }
}
- if (live_kernel == 1)
- printlivelist(i, set, fp, NULL, NULL);
- else
- printdeadlist(i, set, fp, NULL, NULL);
}
/*
* Display ipfilter stateful filtering information
*/
-static void showipstates(ipsp)
-ips_stat_t *ipsp;
+static void showipstates(ipsp, filter)
+ ips_stat_t *ipsp;
+ int *filter;
{
- u_long minlen, maxlen, totallen, *buckets;
- ipftable_t table;
- ipfobj_t obj;
- int i, sz;
+ ipstate_t *is;
+ int i;
/*
* If a list of states hasn't been asked for, only print out stats
*/
if (!(opts & OPT_SHOWLIST)) {
+ showstatestats(ipsp);
+ return;
+ }
- sz = sizeof(*buckets) * ipsp->iss_statesize;
- buckets = (u_long *)malloc(sz);
+ if ((state_fields != NULL) && (nohdrfields == 0)) {
+ for (i = 0; state_fields[i].w_value != 0; i++) {
+ printfieldhdr(statefields, state_fields + i);
+ if (state_fields[i + 1].w_value != 0)
+ printf("\t");
+ }
+ printf("\n");
+ }
- obj.ipfo_rev = IPFILTER_VERSION;
- obj.ipfo_type = IPFOBJ_GTABLE;
- obj.ipfo_size = sizeof(table);
- obj.ipfo_ptr = &table;
+ /*
+ * Print out all the state information currently held in the kernel.
+ */
+ for (is = ipsp->iss_list; is != NULL; ) {
+ ipstate_t ips;
- table.ita_type = IPFTABLE_BUCKETS;
- table.ita_table = buckets;
+ is = fetchstate(is, &ips);
- if (live_kernel == 1) {
- if (ioctl(state_fd, SIOCGTABL, &obj) != 0) {
- free(buckets);
- return;
+ if (is == NULL)
+ break;
+
+ is = ips.is_next;
+ if ((filter != NULL) &&
+ (state_matcharray(&ips, filter) == 0)) {
+ continue;
+ }
+ if (state_fields != NULL) {
+ for (i = 0; state_fields[i].w_value != 0; i++) {
+ printstatefield(&ips, state_fields[i].w_value);
+ if (state_fields[i + 1].w_value != 0)
+ printf("\t");
}
+ printf("\n");
} else {
- if (kmemcpy((char *)buckets,
- (u_long)ipsp->iss_bucketlen, sz)) {
- free(buckets);
- return;
- }
+ printstate(&ips, opts, ipsp->iss_ticks);
}
+ }
+}
- 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 bucket full\n", ipsp->iss_bucketfull);
- PRINTF("\t%lu maximum rule references\n", ipsp->iss_maxref);
- PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\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);
-
- PRINTF("State logging %sabled\n",
- state_logging ? "en" : "dis");
- PRINTF("\nState table bucket statistics:\n");
- PRINTF("\t%lu in use\t\n", ipsp->iss_inuse);
- PRINTF("\t%u%% hash efficiency\n", ipsp->iss_active ?
- (u_int)(ipsp->iss_inuse * 100 / ipsp->iss_active) : 0);
+static void showstatestats(ipsp)
+ ips_stat_t *ipsp;
+{
+ int minlen, maxlen, totallen;
+ ipftable_t table;
+ u_int *buckets;
+ ipfobj_t obj;
+ int i, sz;
- minlen = ipsp->iss_inuse;
- totallen = 0;
- maxlen = 0;
+ /*
+ * If a list of states hasn't been asked for, only print out stats
+ */
- for (i = 0; i < ipsp->iss_statesize; i++) {
- if (buckets[i] > maxlen)
- maxlen = buckets[i];
- if (buckets[i] < minlen)
- minlen = buckets[i];
- totallen += buckets[i];
- }
+ sz = sizeof(*buckets) * ipsp->iss_state_size;
+ buckets = (u_int *)malloc(sz);
- PRINTF("\t%2.2f%% bucket usage\n\t%lu minimal length\n",
- ((float)ipsp->iss_inuse / ipsp->iss_statesize) * 100.0,
- minlen);
- PRINTF("\t%lu maximal length\n\t%.3f average length\n",
- maxlen,
- ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse :
- 0.0);
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_type = IPFOBJ_GTABLE;
+ obj.ipfo_size = sizeof(table);
+ obj.ipfo_ptr = &table;
-#define ENTRIES_PER_LINE 5
+ table.ita_type = IPFTABLE_BUCKETS;
+ table.ita_table = buckets;
- if (opts & OPT_VERBOSE) {
- PRINTF("\nCurrent bucket sizes :\n");
- for (i = 0; i < ipsp->iss_statesize; i++) {
- if ((i % ENTRIES_PER_LINE) == 0)
- PRINTF("\t");
- PRINTF("%4d -> %4lu", i, buckets[i]);
- if ((i % ENTRIES_PER_LINE) ==
- (ENTRIES_PER_LINE - 1))
- PRINTF("\n");
- else
- PRINTF(" ");
- }
- PRINTF("\n");
+ if (live_kernel == 1) {
+ if (ioctl(state_fd, SIOCGTABL, &obj) != 0) {
+ free(buckets);
+ return;
}
- PRINTF("\n");
+ } else {
+ if (kmemcpy((char *)buckets,
+ (u_long)ipsp->iss_bucketlen, sz)) {
+ free(buckets);
+ return;
+ }
+ }
- free(buckets);
+ PRINTF("%u\tactive state table entries\n",ipsp->iss_active);
+ PRINTF("%lu\tadd bad\n", ipsp->iss_add_bad);
+ PRINTF("%lu\tadd duplicate\n", ipsp->iss_add_dup);
+ PRINTF("%lu\tadd locked\n", ipsp->iss_add_locked);
+ PRINTF("%lu\tadd oow\n", ipsp->iss_add_oow);
+ PRINTF("%lu\tbucket full\n", ipsp->iss_bucket_full);
+ PRINTF("%lu\tcheck bad\n", ipsp->iss_check_bad);
+ PRINTF("%lu\tcheck miss\n", ipsp->iss_check_miss);
+ PRINTF("%lu\tcheck nattag\n", ipsp->iss_check_nattag);
+ PRINTF("%lu\tclone nomem\n", ipsp->iss_clone_nomem);
+ PRINTF("%lu\tcheck notag\n", ipsp->iss_check_notag);
+ PRINTF("%lu\tcheck success\n", ipsp->iss_hits);
+ PRINTF("%lu\tcloned\n", ipsp->iss_cloned);
+ PRINTF("%lu\texpired\n", ipsp->iss_expire);
+ PRINTF("%lu\tflush all\n", ipsp->iss_flush_all);
+ PRINTF("%lu\tflush closing\n", ipsp->iss_flush_closing);
+ PRINTF("%lu\tflush queue\n", ipsp->iss_flush_queue);
+ PRINTF("%lu\tflush state\n", ipsp->iss_flush_state);
+ PRINTF("%lu\tflush timeout\n", ipsp->iss_flush_timeout);
+ PRINTF("%u\thash buckets in use\n", ipsp->iss_inuse);
+ PRINTF("%lu\tICMP bad\n", ipsp->iss_icmp_bad);
+ PRINTF("%lu\tICMP banned\n", ipsp->iss_icmp_banned);
+ PRINTF("%lu\tICMP errors\n", ipsp->iss_icmp_icmperr);
+ PRINTF("%lu\tICMP head block\n", ipsp->iss_icmp_headblock);
+ PRINTF("%lu\tICMP hits\n", ipsp->iss_icmp_hits);
+ PRINTF("%lu\tICMP not query\n", ipsp->iss_icmp_notquery);
+ PRINTF("%lu\tICMP short\n", ipsp->iss_icmp_short);
+ PRINTF("%lu\tICMP too many\n", ipsp->iss_icmp_toomany);
+ PRINTF("%lu\tICMPv6 errors\n", ipsp->iss_icmp6_icmperr);
+ PRINTF("%lu\tICMPv6 miss\n", ipsp->iss_icmp6_miss);
+ PRINTF("%lu\tICMPv6 not info\n", ipsp->iss_icmp6_notinfo);
+ PRINTF("%lu\tICMPv6 not query\n", ipsp->iss_icmp6_notquery);
+ PRINTF("%lu\tlog fail\n", ipsp->iss_log_fail);
+ PRINTF("%lu\tlog ok\n", ipsp->iss_log_ok);
+ PRINTF("%lu\tlookup interface mismatch\n", ipsp->iss_lookup_badifp);
+ PRINTF("%lu\tlookup mask mismatch\n", ipsp->iss_miss_mask);
+ PRINTF("%lu\tlookup port mismatch\n", ipsp->iss_lookup_badport);
+ PRINTF("%lu\tlookup miss\n", ipsp->iss_lookup_miss);
+ PRINTF("%lu\tmaximum rule references\n", ipsp->iss_max_ref);
+ PRINTF("%lu\tmaximum hosts per rule\n", ipsp->iss_max_track);
+ PRINTF("%lu\tno memory\n", ipsp->iss_nomem);
+ PRINTF("%lu\tout of window\n", ipsp->iss_oow);
+ PRINTF("%lu\torphans\n", ipsp->iss_orphan);
+ PRINTF("%lu\tscan block\n", ipsp->iss_scan_block);
+ PRINTF("%lu\tstate table maximum reached\n", ipsp->iss_max);
+ PRINTF("%lu\tTCP closing\n", ipsp->iss_tcp_closing);
+ PRINTF("%lu\tTCP OOW\n", ipsp->iss_tcp_oow);
+ PRINTF("%lu\tTCP RST add\n", ipsp->iss_tcp_rstadd);
+ PRINTF("%lu\tTCP too small\n", ipsp->iss_tcp_toosmall);
+ PRINTF("%lu\tTCP bad options\n", ipsp->iss_tcp_badopt);
+ PRINTF("%lu\tTCP removed\n", ipsp->iss_fin);
+ PRINTF("%lu\tTCP FSM\n", ipsp->iss_tcp_fsm);
+ PRINTF("%lu\tTCP strict\n", ipsp->iss_tcp_strict);
+ PRINTF("%lu\tTCP wild\n", ipsp->iss_wild);
+ PRINTF("%lu\tMicrosoft Windows SACK\n", ipsp->iss_winsack);
- if (live_kernel == 1) {
- showtqtable_live(state_fd);
- } else {
- printtqtable(ipsp->iss_tcptab);
+ PRINTF("State logging %sabled\n", state_logging ? "en" : "dis");
+
+ PRINTF("IP states added:\n");
+ for (i = 0; i < 256; i++) {
+ if (ipsp->iss_proto[i] != 0) {
+ struct protoent *proto;
+
+ proto = getprotobynumber(i);
+ PRINTF("%lu", ipsp->iss_proto[i]);
+ if (proto != NULL)
+ PRINTF("\t%s\n", proto->p_name);
+ else
+ PRINTF("\t%d\n", i);
}
+ }
- return;
+ PRINTF("\nState table bucket statistics:\n");
+ PRINTF("%u\tin use\n", ipsp->iss_inuse);
+
+ minlen = ipsp->iss_max;
+ totallen = 0;
+ maxlen = 0;
+ for (i = 0; i < ipsp->iss_state_size; i++) {
+ if (buckets[i] > maxlen)
+ maxlen = buckets[i];
+ if (buckets[i] < minlen)
+ minlen = buckets[i];
+ totallen += buckets[i];
}
- /*
- * Print out all the state information currently held in the kernel.
- */
- while (ipsp->iss_list != NULL) {
- ipstate_t ips;
+ PRINTF("%d\thash efficiency\n",
+ totallen ? ipsp->iss_inuse * 100 / totallen : 0);
+ PRINTF("%2.2f%%\tbucket usage\n%u\tminimal length\n",
+ ((float)ipsp->iss_inuse / ipsp->iss_state_size) * 100.0,
+ minlen);
+ PRINTF("%u\tmaximal length\n%.3f\taverage length\n",
+ maxlen,
+ ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse :
+ 0.0);
- ipsp->iss_list = fetchstate(ipsp->iss_list, &ips);
+#define ENTRIES_PER_LINE 5
- if (ipsp->iss_list != NULL) {
- ipsp->iss_list = ips.is_next;
- printstate(&ips, opts, ipsp->iss_ticks);
+ if (opts & OPT_VERBOSE) {
+ PRINTF("\nCurrent bucket sizes :\n");
+ for (i = 0; i < ipsp->iss_state_size; i++) {
+ if ((i % ENTRIES_PER_LINE) == 0)
+ PRINTF("\t");
+ PRINTF("%4d -> %4u", i, buckets[i]);
+ if ((i % ENTRIES_PER_LINE) ==
+ (ENTRIES_PER_LINE - 1))
+ PRINTF("\n");
+ else
+ PRINTF(" ");
}
+ PRINTF("\n");
+ }
+ PRINTF("\n");
+
+ free(buckets);
+
+ if (live_kernel == 1) {
+ showtqtable_live(state_fd);
+ } else {
+ printtqtable(ipsp->iss_tcptab);
}
}
@@ -1190,21 +1297,23 @@ ips_stat_t *ipsp;
static int handle_resize = 0, handle_break = 0;
static void topipstates(saddr, daddr, sport, dport, protocol, ver,
- refreshtime, topclosed)
-i6addr_t saddr;
-i6addr_t daddr;
-int sport;
-int dport;
-int protocol;
-int ver;
-int refreshtime;
-int topclosed;
+ refreshtime, topclosed, filter)
+ i6addr_t saddr;
+ i6addr_t daddr;
+ int sport;
+ int dport;
+ int protocol;
+ int ver;
+ int refreshtime;
+ int topclosed;
+ int *filter;
{
char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE];
int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT;
int i, j, winy, tsentry, maxx, maxy, redraw = 0, ret = 0;
int len, srclen, dstlen, forward = 1, c = 0;
ips_stat_t ipsst, *ipsstp = &ipsst;
+ int token_type = IPFGENITER_STATE;
statetop_t *tstable = NULL, *tp;
const char *errstr = "";
ipstate_t ips;
@@ -1267,6 +1376,10 @@ int topclosed;
if (ips.is_v != ver)
continue;
+ if ((filter != NULL) &&
+ (state_matcharray(&ips, filter) == 0))
+ continue;
+
/* check v4 src/dest addresses */
if (ips.is_v == 4) {
if ((saddr.in4.s_addr != INADDR_ANY &&
@@ -1348,6 +1461,7 @@ int topclosed;
}
}
+ (void) ioctl(state_fd, SIOCIPFDELTOK, &token_type);
/* sort the array */
if (tsentry != -1) {
@@ -1485,14 +1599,14 @@ int topclosed;
printw("Src: %s, Dest: %s, Proto: %s, Sorted by: %s\n\n",
str1, str2, str3, str4);
- /*
+ /*
* For an IPv4 IP address we need at most 15 characters,
* 4 tuples of 3 digits, separated by 3 dots. Enforce this
* length, so the colums do not change positions based
* on the size of the IP address. This length makes the
- * output fit in a 80 column terminal.
+ * output fit in a 80 column terminal.
* We are lacking a good solution for IPv6 addresses (that
- * can be longer that 15 characters), so we do not enforce
+ * can be longer that 15 characters), so we do not enforce
* a maximum on the IP field size.
*/
if (srclen < 15)
@@ -1629,8 +1743,8 @@ out:
* Show fragment cache information that's held in the kernel.
*/
static void showfrstates(ifsp, ticks)
-ipfrstat_t *ifsp;
-u_long ticks;
+ ipfrstat_t *ifsp;
+ u_long ticks;
{
struct ipfr *ipfrtab[IPFT_SIZE], ifr;
int i;
@@ -1638,13 +1752,13 @@ u_long ticks;
/*
* print out the numeric statistics
*/
- PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n",
+ PRINTF("IP fragment states:\n%lu\tnew\n%lu\texpired\n%lu\thits\n",
ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits);
- PRINTF("\t%lu retrans\n\t%lu too short\n",
+ PRINTF("%lu\tretrans\n%lu\ttoo short\n",
ifsp->ifs_retrans0, ifsp->ifs_short);
- PRINTF("\t%lu no memory\n\t%lu already exist\n",
+ PRINTF("%lu\tno memory\n%lu\talready exist\n",
ifsp->ifs_nomem, ifsp->ifs_exists);
- PRINTF("\t%lu inuse\n", ifsp->ifs_inuse);
+ PRINTF("%lu\tinuse\n", ifsp->ifs_inuse);
PRINTF("\n");
if (live_kernel == 0) {
@@ -1664,7 +1778,7 @@ u_long ticks;
break;
ifr.ipfr_ttl -= ticks;
printfraginfo("", &ifr);
- } while (1);
+ } while (ifr.ipfr_next != NULL);
} else {
for (i = 0; i < IPFT_SIZE; i++)
while (ipfrtab[i] != NULL) {
@@ -1693,7 +1807,7 @@ u_long ticks;
break;
ifr.ipfr_ttl -= ticks;
printfraginfo("NAT: ", &ifr);
- } while (1);
+ } while (ifr.ipfr_next != NULL);
} else {
for (i = 0; i < IPFT_SIZE; i++)
while (ipfrtab[i] != NULL) {
@@ -1711,7 +1825,7 @@ u_long ticks;
* Show stats on how auth within IPFilter has been used
*/
static void showauthstates(asp)
-fr_authstat_t *asp;
+ ipf_authstat_t *asp;
{
frauthent_t *frap, fra;
ipfgeniter_t auth;
@@ -1727,7 +1841,7 @@ fr_authstat_t *asp;
auth.igi_data = &fra;
#ifdef USE_QUAD_T
- printf("Authorisation hits: %qu\tmisses %qu\n",
+ printf("Authorisation hits: %"PRIu64"\tmisses %"PRIu64"\n",
(unsigned long long) asp->fas_hits,
(unsigned long long) asp->fas_miss);
#else
@@ -1762,7 +1876,7 @@ fr_authstat_t *asp;
* authentication, separately.
*/
static void showgroups(fiop)
-struct friostat *fiop;
+ struct friostat *fiop;
{
static char *gnames[3] = { "Filter", "Accounting", "Authentication" };
static int gnums[3] = { IPL_LOGIPF, IPL_LOGCOUNT, IPL_LOGAUTH };
@@ -1790,10 +1904,11 @@ struct friostat *fiop;
}
}
+
static void parse_ipportstr(argument, ip, port)
-const char *argument;
-i6addr_t *ip;
-int *port;
+ const char *argument;
+ i6addr_t *ip;
+ int *port;
{
char *s, *comma;
int ok = 0;
@@ -1845,20 +1960,20 @@ int *port;
#ifdef STATETOP
static void sig_resize(s)
-int s;
+ int s;
{
handle_resize = 1;
}
static void sig_break(s)
-int s;
+ int s;
{
handle_break = 1;
}
static char *getip(v, addr)
-int v;
-i6addr_t *addr;
+ int v;
+ i6addr_t *addr;
{
#ifdef USE_INET6
static char hostbuf[MAXHOSTNAMELEN+1];
@@ -1878,7 +1993,7 @@ i6addr_t *addr;
static char *ttl_to_string(ttl)
-long int ttl;
+ long int ttl;
{
static char ttlbuf[STSTRSIZE];
int hours, minutes, seconds;
@@ -1900,8 +2015,8 @@ long int ttl;
static int sort_pkts(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
@@ -1916,8 +2031,8 @@ const void *b;
static int sort_bytes(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -1931,8 +2046,8 @@ const void *b;
static int sort_p(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -1946,8 +2061,8 @@ const void *b;
static int sort_ttl(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -1960,8 +2075,8 @@ const void *b;
}
static int sort_srcip(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -1986,8 +2101,8 @@ const void *b;
}
static int sort_srcpt(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -2000,8 +2115,8 @@ const void *b;
}
static int sort_dstip(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -2026,8 +2141,8 @@ const void *b;
}
static int sort_dstpt(a, b)
-const void *a;
-const void *b;
+ const void *a;
+ const void *b;
{
register const statetop_t *ap = a;
register const statetop_t *bp = b;
@@ -2043,9 +2158,8 @@ const void *b;
ipstate_t *fetchstate(src, dst)
-ipstate_t *src, *dst;
+ ipstate_t *src, *dst;
{
- int i;
if (live_kernel == 1) {
ipfgeniter_t state;
@@ -2063,8 +2177,8 @@ ipstate_t *src, *dst;
if (ioctl(state_fd, SIOCGENITER, &obj) != 0)
return NULL;
if (dst->is_next == NULL) {
- i = IPFGENITER_STATE;
- ioctl(state_fd, SIOCIPFDELTOK, &i);
+ int n = IPFGENITER_STATE;
+ (void) ioctl(ipf_fd,SIOCIPFDELTOK, &n);
}
} else {
if (kmemcpy((char *)dst, (u_long)src, sizeof(*dst)))
@@ -2075,8 +2189,8 @@ ipstate_t *src, *dst;
static int fetchfrag(fd, type, frp)
-int fd, type;
-ipfr_t *frp;
+ int fd, type;
+ ipfr_t *frp;
{
ipfgeniter_t frag;
ipfobj_t obj;
@@ -2096,8 +2210,155 @@ ipfr_t *frp;
}
+static int state_matcharray(stp, array)
+ ipstate_t *stp;
+ int *array;
+{
+ int i, n, *x, rv, p;
+ ipfexp_t *e;
+
+ rv = 0;
+
+ for (n = array[0], x = array + 1; n > 0; x += e->ipfe_size) {
+ e = (ipfexp_t *)x;
+ if (e->ipfe_cmd == IPF_EXP_END)
+ break;
+ n -= e->ipfe_size;
+
+ rv = 0;
+ /*
+ * The upper 16 bits currently store the protocol value.
+ * This is currently used with TCP and UDP port compares and
+ * allows "tcp.port = 80" without requiring an explicit
+ " "ip.pr = tcp" first.
+ */
+ p = e->ipfe_cmd >> 16;
+ if ((p != 0) && (p != stp->is_p))
+ break;
+
+ switch (e->ipfe_cmd)
+ {
+ case IPF_EXP_IP_PR :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (stp->is_p == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_IP_SRCADDR :
+ if (stp->is_v != 4)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= ((stp->is_saddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]);
+ }
+ break;
+
+ case IPF_EXP_IP_DSTADDR :
+ if (stp->is_v != 4)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= ((stp->is_daddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]);
+ }
+ break;
+
+ case IPF_EXP_IP_ADDR :
+ if (stp->is_v != 4)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= ((stp->is_saddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]) ||
+ ((stp->is_daddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]);
+ }
+ break;
+
+#ifdef USE_INET6
+ case IPF_EXP_IP6_SRCADDR :
+ if (stp->is_v != 6)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= IP6_MASKEQ(&stp->is_src,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]);
+ }
+ break;
+
+ case IPF_EXP_IP6_DSTADDR :
+ if (stp->is_v != 6)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= IP6_MASKEQ(&stp->is_dst,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]);
+ }
+ break;
+
+ case IPF_EXP_IP6_ADDR :
+ if (stp->is_v != 6)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= IP6_MASKEQ(&stp->is_src,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]) ||
+ IP6_MASKEQ(&stp->is_dst,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]);
+ }
+ break;
+#endif
+
+ case IPF_EXP_UDP_PORT :
+ case IPF_EXP_TCP_PORT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (stp->is_sport == e->ipfe_arg0[i]) ||
+ (stp->is_dport == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_UDP_SPORT :
+ case IPF_EXP_TCP_SPORT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (stp->is_sport == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_UDP_DPORT :
+ case IPF_EXP_TCP_DPORT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (stp->is_dport == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_IDLE_GT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (stp->is_die < e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_TCP_STATE :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (stp->is_state[0] == e->ipfe_arg0[i]) ||
+ (stp->is_state[1] == e->ipfe_arg0[i]);
+ }
+ break;
+ }
+ rv ^= e->ipfe_not;
+
+ if (rv == 0)
+ break;
+ }
+
+ return rv;
+}
+
+
static void showtqtable_live(fd)
-int fd;
+ int fd;
{
ipftq_t table[IPF_TCP_NSTATES];
ipfobj_t obj;
diff --git a/contrib/ipfilter/tools/ipfsyncd.c b/contrib/ipfilter/tools/ipfsyncd.c
new file mode 100644
index 000000000000..d4671e409d63
--- /dev/null
+++ b/contrib/ipfilter/tools/ipfsyncd.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright (C) 2012 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipfsyncd.c,v 1.1.2.2 2012/07/22 08:04:24 darren_r Exp $";
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#include <sys/errno.h>
+
+#include <netinet/in.h>
+#include <net/if.h>
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <signal.h>
+
+#include "ipf.h"
+#include "opts.h"
+
+
+#define R_IO_ERROR -1
+#define R_OKAY 0
+#define R_MORE 1
+#define R_SKIP 2
+#if defined(sun) && !defined(SOLARIS2)
+# define STRERROR(x) sys_errlist[x]
+extern char *sys_errlist[];
+#else
+# define STRERROR(x) strerror(x)
+#endif
+
+
+int main __P((int, char *[]));
+void usage __P((char *));
+void printsynchdr __P((synchdr_t *));
+void printtable __P((int));
+void printsmcproto __P((char *));
+void printcommand __P((int));
+int do_kbuff __P((int, char *, int *));
+int do_packet __P((int, char *));
+int buildsocket __P((char *, struct sockaddr_in *));
+void do_io __P((void));
+void handleterm __P((int));
+
+int terminate = 0;
+int igmpfd = -1;
+int nfd = -1;
+int lfd = -1;
+int opts = 0;
+
+void
+usage(progname)
+ char *progname;
+{
+ fprintf(stderr,
+ "Usage: %s [-d] [-p port] [-i address] -I <interface>\n",
+ progname);
+}
+
+void
+handleterm(sig)
+ int sig;
+{
+ terminate = sig;
+}
+
+
+/* should be large enough to hold header + any datatype */
+#define BUFFERLEN 1400
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct sockaddr_in sin;
+ char *interface;
+ char *progname;
+ int opt, tries;
+
+ progname = strrchr(argv[0], '/');
+ if (progname) {
+ progname++;
+ } else {
+ progname = argv[0];
+ }
+
+ opts = 0;
+ tries = 0;
+ interface = NULL;
+
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(0xaf6c);
+ sin.sin_addr.s_addr = htonl(INADDR_UNSPEC_GROUP | 0x697066);
+
+ while ((opt = getopt(argc, argv, "di:I:p:")) != -1)
+ switch (opt)
+ {
+ case 'd' :
+ debuglevel++;
+ break;
+ case 'I' :
+ interface = optarg;
+ break;
+ case 'i' :
+ sin.sin_addr.s_addr = inet_addr(optarg);
+ break;
+ case 'p' :
+ sin.sin_port = htons(atoi(optarg));
+ break;
+ }
+
+ if (interface == NULL) {
+ usage(progname);
+ exit(1);
+ }
+
+ if (!debuglevel) {
+
+#if BSD >= 199306
+ daemon(0, 0);
+#else
+ int fd = open("/dev/null", O_RDWR);
+
+ switch (fork())
+ {
+ case 0 :
+ break;
+
+ case -1 :
+ fprintf(stderr, "%s: fork() failed: %s\n",
+ argv[0], STRERROR(errno));
+ exit(1);
+ /* NOTREACHED */
+
+ default :
+ exit(0);
+ /* NOTREACHED */
+ }
+
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ close(fd);
+
+ setsid();
+#endif
+ }
+
+ signal(SIGHUP, handleterm);
+ signal(SIGINT, handleterm);
+ signal(SIGTERM, handleterm);
+
+ openlog(progname, LOG_PID, LOG_SECURITY);
+
+ while (!terminate) {
+ if (lfd != -1) {
+ close(lfd);
+ lfd = -1;
+ }
+ if (nfd != -1) {
+ close(nfd);
+ nfd = -1;
+ }
+ if (igmpfd != -1) {
+ close(igmpfd);
+ igmpfd = -1;
+ }
+
+ if (buildsocket(interface, &sin) == -1)
+ goto tryagain;
+
+ lfd = open(IPSYNC_NAME, O_RDWR);
+ if (lfd == -1) {
+ syslog(LOG_ERR, "open(%s):%m", IPSYNC_NAME);
+ debug(1, "open(%s): %s\n", IPSYNC_NAME,
+ STRERROR(errno));
+ goto tryagain;
+ }
+
+ tries = -1;
+ do_io();
+tryagain:
+ tries++;
+ syslog(LOG_INFO, "retry in %d seconds", 1 << tries);
+ debug(1, "wait %d seconds\n", 1 << tries);
+ sleep(1 << tries);
+ }
+
+
+ /* terminate */
+ if (lfd != -1)
+ close(lfd);
+ if (nfd != -1)
+ close(nfd);
+
+ syslog(LOG_ERR, "signal %d received, exiting...", terminate);
+ debug(1, "signal %d received, exiting...", terminate);
+
+ exit(1);
+}
+
+
+void
+do_io()
+{
+ char nbuff[BUFFERLEN];
+ char buff[BUFFERLEN];
+ fd_set mrd, rd;
+ int maxfd;
+ int inbuf;
+ int n1;
+ int left;
+
+ FD_ZERO(&mrd);
+ FD_SET(lfd, &mrd);
+ FD_SET(nfd, &mrd);
+ maxfd = nfd;
+ if (lfd > maxfd)
+ maxfd = lfd;
+ debug(2, "nfd %d lfd %d maxfd %d\n", nfd, lfd, maxfd);
+
+ inbuf = 0;
+ /*
+ * A threaded approach to this loop would have one thread
+ * work on reading lfd (only) all the time and another thread
+ * working on reading nfd all the time.
+ */
+ while (!terminate) {
+ int n;
+
+ rd = mrd;
+
+ n = select(maxfd + 1, &rd, NULL, NULL, NULL);
+ if (n < 0) {
+ switch (errno)
+ {
+ case EINTR :
+ continue;
+ default :
+ syslog(LOG_ERR, "select error: %m");
+ debug(1, "select error: %s\n", STRERROR(errno));
+ return;
+ }
+ }
+
+ if (FD_ISSET(lfd, &rd)) {
+ n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf);
+
+ debug(3, "read(K):%d\n", n1);
+
+ if (n1 <= 0) {
+ syslog(LOG_ERR, "read error (k-header): %m");
+ debug(1, "read error (k-header): %s\n",
+ STRERROR(errno));
+ return;
+ }
+
+ left = 0;
+
+ switch (do_kbuff(n1, buff, &left))
+ {
+ case R_IO_ERROR :
+ return;
+ case R_MORE :
+ inbuf += left;
+ break;
+ default :
+ inbuf = 0;
+ break;
+ }
+ }
+
+ if (FD_ISSET(nfd, &rd)) {
+ n1 = recv(nfd, nbuff, sizeof(nbuff), 0);
+
+ debug(3, "read(N):%d\n", n1);
+
+ if (n1 <= 0) {
+ syslog(LOG_ERR, "read error (n-header): %m");
+ debug(1, "read error (n-header): %s\n",
+ STRERROR(errno));
+ return;
+ }
+
+ switch (do_packet(n1, nbuff))
+ {
+ case R_IO_ERROR :
+ return;
+ default :
+ break;
+ }
+ }
+ }
+}
+
+
+int
+buildsocket(nicname, sinp)
+ char *nicname;
+ struct sockaddr_in *sinp;
+{
+ struct sockaddr_in *reqip;
+ struct ifreq req;
+ char opt;
+
+ debug(2, "binding to %s:%s\n", nicname, inet_ntoa(sinp->sin_addr));
+
+ if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
+ struct in_addr addr;
+ struct ip_mreq mreq;
+
+ igmpfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
+ if (igmpfd == -1) {
+ syslog(LOG_ERR, "socket:%m");
+ debug(1, "socket:%s\n", STRERROR(errno));
+ return -1;
+ }
+
+ bzero((char *)&req, sizeof(req));
+ strncpy(req.ifr_name, nicname, sizeof(req.ifr_name));
+ req.ifr_name[sizeof(req.ifr_name) - 1] = '\0';
+ if (ioctl(igmpfd, SIOCGIFADDR, &req) == -1) {
+ syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m");
+ debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno));
+ close(igmpfd);
+ igmpfd = -1;
+ return -1;
+ }
+ reqip = (struct sockaddr_in *)&req.ifr_addr;
+
+ addr = reqip->sin_addr;
+ if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_IF,
+ (char *)&addr, sizeof(addr)) == -1) {
+ syslog(LOG_ERR, "setsockopt(IP_MULTICAST_IF(%s)):%m",
+ inet_ntoa(addr));
+ debug(1, "setsockopt(IP_MULTICAST_IF(%s)):%s\n",
+ inet_ntoa(addr), STRERROR(errno));
+ close(igmpfd);
+ igmpfd = -1;
+ return -1;
+ }
+
+ opt = 0;
+ if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_LOOP,
+ (char *)&opt, sizeof(opt)) == -1) {
+ syslog(LOG_ERR, "setsockopt(IP_MULTICAST_LOOP=0):%m");
+ debug(1, "setsockopt(IP_MULTICAST_LOOP=0):%s\n",
+ STRERROR(errno));
+ close(igmpfd);
+ igmpfd = -1;
+ return -1;
+ }
+
+ opt = 63;
+ if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_TTL,
+ (char *)&opt, sizeof(opt)) == -1) {
+ syslog(LOG_ERR, "setsockopt(IP_MULTICAST_TTL=%d):%m",
+ opt);
+ debug(1, "setsockopt(IP_MULTICAST_TTL=%d):%s\n", opt,
+ STRERROR(errno));
+ close(igmpfd);
+ igmpfd = -1;
+ return -1;
+ }
+
+ mreq.imr_multiaddr.s_addr = sinp->sin_addr.s_addr;
+ mreq.imr_interface.s_addr = reqip->sin_addr.s_addr;
+
+ if (setsockopt(igmpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *)&mreq, sizeof(mreq)) == -1) {
+ char buffer[80];
+
+ sprintf(buffer, "%s,", inet_ntoa(sinp->sin_addr));
+ strcat(buffer, inet_ntoa(reqip->sin_addr));
+
+ syslog(LOG_ERR,
+ "setsockpt(IP_ADD_MEMBERSHIP,%s):%m", buffer);
+ debug(1, "setsockpt(IP_ADD_MEMBERSHIP,%s):%s\n",
+ buffer, STRERROR(errno));
+ close(igmpfd);
+ igmpfd = -1;
+ return -1;
+ }
+ }
+ nfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (nfd == -1) {
+ syslog(LOG_ERR, "socket:%m");
+ if (igmpfd != -1) {
+ close(igmpfd);
+ igmpfd = -1;
+ }
+ return -1;
+ }
+ bzero((char *)&req, sizeof(req));
+ strncpy(req.ifr_name, nicname, sizeof(req.ifr_name));
+ req.ifr_name[sizeof(req.ifr_name) - 1] = '\0';
+ if (ioctl(nfd, SIOCGIFADDR, &req) == -1) {
+ syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m");
+ debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno));
+ close(igmpfd);
+ igmpfd = -1;
+ return -1;
+ }
+
+ if (bind(nfd, (struct sockaddr *)&req.ifr_addr,
+ sizeof(req.ifr_addr)) == -1) {
+ syslog(LOG_ERR, "bind:%m");
+ debug(1, "bind:%s\n", STRERROR(errno));
+ close(nfd);
+ if (igmpfd != -1) {
+ close(igmpfd);
+ igmpfd = -1;
+ }
+ nfd = -1;
+ return -1;
+ }
+
+ if (connect(nfd, (struct sockaddr *)sinp, sizeof(*sinp)) == -1) {
+ syslog(LOG_ERR, "connect:%m");
+ debug(1, "connect:%s\n", STRERROR(errno));
+ close(nfd);
+ if (igmpfd != -1) {
+ close(igmpfd);
+ igmpfd = -1;
+ }
+ nfd = -1;
+ return -1;
+ }
+ syslog(LOG_INFO, "Sending data to %s", inet_ntoa(sinp->sin_addr));
+ debug(3, "Sending data to %s\n", inet_ntoa(sinp->sin_addr));
+
+ return nfd;
+}
+
+
+int
+do_packet(pklen, buff)
+ int pklen;
+ char *buff;
+{
+ synchdr_t *sh;
+ u_32_t magic;
+ int len;
+ int n2;
+ int n3;
+
+ while (pklen > 0) {
+ if (pklen < sizeof(*sh)) {
+ syslog(LOG_ERR, "packet length too short:%d", pklen);
+ debug(2, "packet length too short:%d\n", pklen);
+ return R_SKIP;
+ }
+
+ sh = (synchdr_t *)buff;
+ len = ntohl(sh->sm_len);
+ magic = ntohl(sh->sm_magic);
+
+ if (magic != SYNHDRMAGIC) {
+ syslog(LOG_ERR, "invalid header magic %x", magic);
+ debug(2, "invalid header magic %x\n", magic);
+ return R_SKIP;
+ }
+
+ if (pklen < len + sizeof(*sh)) {
+ syslog(LOG_ERR, "packet length too short:%d", pklen);
+ debug(2, "packet length too short:%d\n", pklen);
+ return R_SKIP;
+ }
+
+ if (debuglevel > 3) {
+ printsynchdr(sh);
+ printcommand(sh->sm_cmd);
+ printtable(sh->sm_table);
+ printsmcproto(buff);
+ }
+
+ n2 = sizeof(*sh) + len;
+
+ do {
+ n3 = write(lfd, buff, n2);
+ if (n3 <= 0) {
+ syslog(LOG_ERR, "write error: %m");
+ debug(1, "write error: %s\n", STRERROR(errno));
+ return R_IO_ERROR;
+ }
+
+ n2 -= n3;
+ buff += n3;
+ pklen -= n3;
+ } while (n3 != 0);
+ }
+
+ return R_OKAY;
+}
+
+
+
+int
+do_kbuff(inbuf, buf, left)
+ int inbuf, *left;
+ char *buf;
+{
+ synchdr_t *sh;
+ u_32_t magic;
+ int complete;
+ int sendlen;
+ int error;
+ int bytes;
+ int len;
+ int n2;
+ int n3;
+
+ sendlen = 0;
+ bytes = inbuf;
+ error = R_OKAY;
+ sh = (synchdr_t *)buf;
+
+ for (complete = 0; bytes > 0; complete++) {
+ len = ntohl(sh->sm_len);
+ magic = ntohl(sh->sm_magic);
+
+ if (magic != SYNHDRMAGIC) {
+ syslog(LOG_ERR,
+ "read invalid header magic 0x%x, flushing",
+ magic);
+ debug(2, "read invalid header magic 0x%x, flushing\n",
+ magic);
+ n2 = SMC_RLOG;
+ (void) ioctl(lfd, SIOCIPFFL, &n2);
+ break;
+ }
+
+ if (debuglevel > 3) {
+ printsynchdr(sh);
+ printcommand(sh->sm_cmd);
+ printtable(sh->sm_table);
+ putchar('\n');
+ }
+
+ if (bytes < sizeof(*sh) + len) {
+ debug(3, "Not enough bytes %d < %d\n", bytes,
+ sizeof(*sh) + len);
+ error = R_MORE;
+ break;
+ }
+
+ if (debuglevel > 3) {
+ printsmcproto(buf);
+ }
+
+ sendlen += len + sizeof(*sh);
+ sh = (synchdr_t *)(buf + sendlen);
+ bytes -= sendlen;
+ }
+
+ if (complete) {
+ n3 = send(nfd, buf, sendlen, 0);
+ if (n3 <= 0) {
+ syslog(LOG_ERR, "write error: %m");
+ debug(1, "write error: %s\n", STRERROR(errno));
+ return R_IO_ERROR;
+ }
+ debug(3, "send on %d len %d = %d\n", nfd, sendlen, n3);
+ error = R_OKAY;
+ }
+
+ /* move buffer to the front,we might need to make
+ * this more efficient, by using a rolling pointer
+ * over the buffer and only copying it, when
+ * we are reaching the end
+ */
+ if (bytes > 0) {
+ bcopy(buf + bytes, buf, bytes);
+ error = R_MORE;
+ }
+ debug(4, "complete %d bytes %d error %d\n", complete, bytes, error);
+
+ *left = bytes;
+
+ return error;
+}
+
+
+void
+printcommand(cmd)
+ int cmd;
+{
+
+ switch (cmd)
+ {
+ case SMC_CREATE :
+ printf(" cmd:CREATE");
+ break;
+ case SMC_UPDATE :
+ printf(" cmd:UPDATE");
+ break;
+ default :
+ printf(" cmd:Unknown(%d)", cmd);
+ break;
+ }
+}
+
+
+void
+printtable(table)
+ int table;
+{
+ switch (table)
+ {
+ case SMC_NAT :
+ printf(" table:NAT");
+ break;
+ case SMC_STATE :
+ printf(" table:STATE");
+ break;
+ default :
+ printf(" table:Unknown(%d)", table);
+ break;
+ }
+}
+
+
+void
+printsmcproto(buff)
+ char *buff;
+{
+ syncupdent_t *su;
+ synchdr_t *sh;
+
+ sh = (synchdr_t *)buff;
+
+ if (sh->sm_cmd == SMC_CREATE) {
+ ;
+
+ } else if (sh->sm_cmd == SMC_UPDATE) {
+ su = (syncupdent_t *)buff;
+ if (sh->sm_p == IPPROTO_TCP) {
+ printf(" TCP Update: age %lu state %d/%d\n",
+ su->sup_tcp.stu_age,
+ su->sup_tcp.stu_state[0],
+ su->sup_tcp.stu_state[1]);
+ }
+ } else {
+ printf("Unknown command\n");
+ }
+}
+
+
+void
+printsynchdr(sh)
+ synchdr_t *sh;
+{
+
+ printf("v:%d p:%d num:%d len:%d magic:%x", sh->sm_v, sh->sm_p,
+ ntohl(sh->sm_num), ntohl(sh->sm_len), ntohl(sh->sm_magic));
+}
diff --git a/contrib/ipfilter/tools/ipftest.c b/contrib/ipfilter/tools/ipftest.c
index 963ed197cb9c..a475828b2e8f 100644
--- a/contrib/ipfilter/tools/ipftest.c
+++ b/contrib/ipfilter/tools/ipftest.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2002-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -12,24 +12,23 @@
#if !defined(lint)
static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipftest.c,v 1.44.2.13 2006/12/12 16:13:01 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
extern char *optarg;
-extern struct frentry *ipfilter[2][2];
-extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex;
+extern struct ipread pcap, iptext, iphex;
extern struct ifnet *get_unit __P((char *, int));
extern void init_ifp __P((void));
extern ipnat_t *natparse __P((char *, int));
-extern int fr_running;
extern hostmap_t **ipf_hm_maptable;
extern hostmap_t *ipf_hm_maplist;
-ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert;
+ipfmutex_t ipl_mutex, ipf_auth_mx, ipf_rw, ipf_stinsert;
ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock;
ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw, ipf_frcache;
-ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth, ipf_tokens;
-int opts = OPT_DONOTHING;
+ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_authlk;
+ipfrwlock_t ipf_tokens;
+int opts = OPT_DONTOPEN;
int use_inet6 = 0;
int docksum = 0;
int pfil_delayed_copy = 0;
@@ -37,10 +36,10 @@ int main __P((int, char *[]));
int loadrules __P((char *, int));
int kmemcpy __P((char *, long, int));
int kstrncpy __P((char *, long, int n));
-void dumpnat __P((void));
-void dumpstate __P((void));
-void dumplookups __P((void));
-void dumpgroups __P((void));
+int blockreason;
+void dumpnat __P((void *));
+void dumpgroups __P((ipf_main_softc_t *));
+void dumprules __P((frentry_t *));
void drain_log __P((char *));
void fixv4sums __P((mb_t *, ip_t *));
@@ -72,18 +71,20 @@ static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ipftestioctl,
ipscantestioctl,
ipooltestioctl,
NULL };
+static ipf_main_softc_t *softc = NULL;
-int main(argc,argv)
-int argc;
-char *argv[];
+int
+main(argc,argv)
+ int argc;
+ char *argv[];
{
char *datain, *iface, *ifname, *logout;
int fd, i, dir, c, loaded, dump, hlen;
struct in_addr sip;
struct ifnet *ifp;
struct ipread *r;
- mb_t mb, *m;
+ mb_t mb, *m, *n;
ip_t *ip;
m = &mb;
@@ -98,18 +99,20 @@ char *argv[];
sip.s_addr = 0;
ifname = "anon0";
- MUTEX_INIT(&ipf_rw, "ipf rw mutex");
- MUTEX_INIT(&ipf_timeoutlock, "ipf timeout lock");
- RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
- RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
- RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock");
- RWLOCK_INIT(&ipf_frcache, "ipf filter cache");
- RWLOCK_INIT(&ipf_tokens, "ipf token rwlock");
-
initparse();
- if (fr_initialise() == -1)
- abort();
- fr_running = 1;
+
+ ipf_load_all();
+
+ softc = ipf_create_all(NULL);
+ if (softc == NULL)
+ exit(1);
+
+ if (ipf_init_all(softc) == -1)
+ exit(1);
+
+ i = 1;
+ if (ipftestioctl(IPL_LOGIPF, SIOCFRENB, &i) != 0)
+ exit(1);
while ((c = getopt(argc, argv, "6bCdDF:i:I:l:N:P:or:RS:T:vxX")) != -1)
switch (c)
@@ -137,12 +140,6 @@ char *argv[];
case 'F' :
if (strcasecmp(optarg, "pcap") == 0)
r = &pcap;
- else if (strcasecmp(optarg, "etherfind") == 0)
- r = &etherf;
- else if (strcasecmp(optarg, "snoop") == 0)
- r = &snoop;
- else if (strcasecmp(optarg, "tcpdump") == 0)
- r = &tcpd;
else if (strcasecmp(optarg, "hex") == 0)
r = &iphex;
else if (strcasecmp(optarg, "text") == 0)
@@ -208,18 +205,21 @@ char *argv[];
else
fd = (*r->r_open)("-");
- if (fd < 0)
+ if (fd < 0) {
+ perror("error opening input");
exit(-1);
+ }
+
+ m->m_data = (char *)m->mb_buf;
+ while ((i = (*r->r_readip)(m, &iface, &dir)) > 0) {
- ip = MTOD(m, ip_t *);
- while ((i = (*r->r_readip)(MTOD(m, char *), sizeof(m->mb_buf),
- &iface, &dir)) > 0) {
if ((iface == NULL) || (*iface == '\0'))
iface = ifname;
+
+ ip = MTOD(m, ip_t *);
ifp = get_unit(iface, IP_V(ip));
- if (!use_inet6) {
- ip->ip_off = ntohs(ip->ip_off);
- ip->ip_len = ntohs(ip->ip_len);
+
+ if (IP_V(ip) == 4) {
if ((r->r_flags & R_DO_CKSUM) || docksum)
fixv4sums(m, ip);
hlen = IP_HL(ip) << 2;
@@ -231,9 +231,11 @@ char *argv[];
hlen = sizeof(ip6_t);
#endif
/* ipfr_slowtimer(); */
+ blockreason = 0;
m = &mb;
+ m->mb_ifp = ifp;
m->mb_len = i;
- i = fr_check(ip, hlen, ifp, dir, &m);
+ i = ipf_check(softc, ip, hlen, ifp, dir, &m);
if ((opts & OPT_NAT) == 0)
switch (i)
{
@@ -271,17 +273,24 @@ char *argv[];
(void)printf("recognised return %#x\n", i);
break;
}
- if (!use_inet6) {
- ip->ip_off = htons(ip->ip_off);
- ip->ip_len = htons(ip->ip_len);
- }
if (!(opts & OPT_BRIEF)) {
putchar(' ');
- printpacket(ip);
+ if (m != NULL)
+ printpacket(dir, m);
+ else
+ printpacket(dir, &mb);
printf("--------------");
- } else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF))
- printpacket(ip);
+ } else if ((opts & (OPT_BRIEF|OPT_NAT)) ==
+ (OPT_NAT|OPT_BRIEF)) {
+ if (m != NULL)
+ printpacket(dir, m);
+ else
+ PRINTF("%d\n", blockreason);
+ }
+
+ ipf_state_flush(softc, 1, 0);
+
if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL))
#if defined(__sgi) && (IRIX < 60500)
(*ifp->if_output)(ifp, (void *)m, NULL);
@@ -292,6 +301,13 @@ char *argv[];
(*ifp->if_output)(ifp, (void *)m, NULL, 0);
# endif
#endif
+
+ while ((m != NULL) && (m != &mb)) {
+ n = m->mb_next;
+ freembt(m);
+ m = n;
+ }
+
if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF))
putchar('\n');
dir = 0;
@@ -300,6 +316,7 @@ char *argv[];
iface = ifname;
}
m = &mb;
+ m->mb_data = (char *)m->mb_buf;
}
if (i != 0)
@@ -311,14 +328,25 @@ char *argv[];
}
if (dump == 1) {
- dumpnat();
- dumpstate();
- dumplookups();
- dumpgroups();
+ dumpnat(softc->ipf_nat_soft);
+ ipf_state_dump(softc, softc->ipf_state_soft);
+ ipf_lookup_dump(softc, softc->ipf_state_soft);
+ dumpgroups(softc);
}
- fr_deinitialise();
+ ipf_fini_all(softc);
+
+ ipf_destroy_all(softc);
+
+ ipf_unload_all();
+ ipf_mutex_clean();
+ ipf_rwlock_clean();
+
+ if (getenv("FINDLEAKS")) {
+ fflush(stdout);
+ abort();
+ }
return 0;
}
@@ -332,14 +360,15 @@ int ipftestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD);
if (opts & OPT_DEBUG)
- fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n",
- (u_int)cmd, data, i);
+ fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n",
+ (u_int)cmd, data, i, softc->ipf_interror);
if (i != 0) {
errno = i;
return -1;
@@ -354,13 +383,14 @@ int ipnattestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD);
if (opts & OPT_DEBUG)
- fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n",
+ fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n",
(u_int)cmd, data, i);
if (i != 0) {
errno = i;
@@ -376,13 +406,14 @@ int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n",
+ fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n",
(u_int)cmd, data, i);
if (i != 0) {
errno = i;
@@ -398,13 +429,14 @@ int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n",
+ fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n",
(u_int)cmd, data, i);
if (i != 0) {
errno = i;
@@ -420,13 +452,14 @@ int ipscantestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n",
+ fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n",
(u_int)cmd, data, i);
if (i != 0) {
errno = i;
@@ -442,13 +475,14 @@ int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n",
+ fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n",
(u_int)cmd, data, i);
if (i != 0) {
errno = i;
@@ -464,14 +498,15 @@ int ipooltestioctl(int dev, ioctlcmd_t cmd, ...)
va_list ap;
int i;
+ dev = dev; /* gcc -Wextra */
va_start(ap, cmd);
data = va_arg(ap, caddr_t);
va_end(ap);
- i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
+ i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n",
- (u_int)cmd, data, i);
+ fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n",
+ (u_int)cmd, data, i, softc->ipf_interror);
if (i != 0) {
errno = i;
return -1;
@@ -480,15 +515,17 @@ int ipooltestioctl(int dev, ioctlcmd_t cmd, ...)
}
#else
int ipftestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n",
+ cmd, data, i, softc->ipf_interror);
if (i != 0) {
errno = i;
return -1;
@@ -498,15 +535,16 @@ void *data;
int ipnattestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n", cmd, data, i);
if (i != 0) {
errno = i;
return -1;
@@ -516,15 +554,16 @@ void *data;
int ipstatetestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n", cmd, data, i);
if (i != 0) {
errno = i;
return -1;
@@ -534,15 +573,16 @@ void *data;
int ipauthtestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n", cmd, data, i);
if (i != 0) {
errno = i;
return -1;
@@ -552,15 +592,16 @@ void *data;
int ipsynctestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n", cmd, data, i);
if (i != 0) {
errno = i;
return -1;
@@ -570,15 +611,16 @@ void *data;
int ipscantestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD);
if ((opts & OPT_DEBUG) || (i != 0))
- fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n", cmd, data, i);
if (i != 0) {
errno = i;
return -1;
@@ -588,15 +630,17 @@ void *data;
int ipooltestioctl(dev, cmd, data)
-dev_t dev;
-ioctlcmd_t cmd;
-void *data;
+ dev_t dev;
+ ioctlcmd_t cmd;
+ void *data;
{
int i;
- i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
+ dev = dev; /* gcc -Wextra */
+ i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD);
if (opts & OPT_DEBUG)
- fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", cmd, data, i);
+ fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n",
+ cmd, data, i, softc->ipf_interror);
if (i != 0) {
errno = i;
return -1;
@@ -607,9 +651,9 @@ void *data;
int kmemcpy(addr, offset, size)
-char *addr;
-long offset;
-int size;
+ char *addr;
+ long offset;
+ int size;
{
bcopy((char *)offset, addr, size);
return 0;
@@ -617,9 +661,9 @@ int size;
int kstrncpy(buf, pos, n)
-char *buf;
-long pos;
-int n;
+ char *buf;
+ long pos;
+ int n;
{
char *ptr;
@@ -634,100 +678,91 @@ int n;
/*
* Display the built up NAT table rules and mapping entries.
*/
-void dumpnat()
+void dumpnat(arg)
+ void *arg;
{
+ ipf_nat_softc_t *softn = arg;
hostmap_t *hm;
ipnat_t *ipn;
nat_t *nat;
printf("List of active MAP/Redirect filters:\n");
- for (ipn = nat_list; ipn != NULL; ipn = ipn->in_next)
+ for (ipn = softn->ipf_nat_list; ipn != NULL; ipn = ipn->in_next)
printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
printf("\nList of active sessions:\n");
- for (nat = nat_instances; nat; nat = nat->nat_next) {
- printactivenat(nat, opts, 0, 0);
+ for (nat = softn->ipf_nat_instances; nat; nat = nat->nat_next) {
+ printactivenat(nat, opts, 0);
if (nat->nat_aps)
- printaps(nat->nat_aps, opts);
+ printf("\tproxy active\n");
}
printf("\nHostmap table:\n");
- for (hm = ipf_hm_maplist; hm != NULL; hm = hm->hm_next)
- printhostmap(hm, 0);
-}
-
-
-/*
- * Display the built up state table rules and mapping entries.
- */
-void dumpstate()
-{
- ipstate_t *ips;
-
- printf("List of active state sessions:\n");
- for (ips = ips_list; ips != NULL; )
- ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE),
- fr_ticks);
+ for (hm = softn->ipf_hm_maplist; hm != NULL; hm = hm->hm_next)
+ printhostmap(hm, hm->hm_hv);
}
-void dumplookups()
-{
- iphtable_t *iph;
- ip_pool_t *ipl;
- int i;
-
- printf("List of configured pools\n");
- for (i = 0; i < IPL_LOGSIZE; i++)
- for (ipl = ip_pool_list[i]; ipl != NULL; ipl = ipl->ipo_next)
- printpool(ipl, bcopywrap, NULL, opts);
-
- printf("List of configured hash tables\n");
- for (i = 0; i < IPL_LOGSIZE; i++)
- for (iph = ipf_htables[i]; iph != NULL; iph = iph->iph_next)
- printhash(iph, bcopywrap, NULL, opts);
-}
-
-
-void dumpgroups()
+void dumpgroups(softc)
+ ipf_main_softc_t *softc;
{
frgroup_t *fg;
- frentry_t *fr;
int i;
printf("List of groups configured (set 0)\n");
for (i = 0; i < IPL_LOGSIZE; i++)
- for (fg = ipfgroups[i][0]; fg != NULL; fg = fg->fg_next) {
+ for (fg = softc->ipf_groups[i][0]; fg != NULL;
+ fg = fg->fg_next) {
printf("Dev.%d. Group %s Ref %d Flags %#x\n",
i, fg->fg_name, fg->fg_ref, fg->fg_flags);
- for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) {
-#ifdef USE_QUAD_T
- printf("%qu ",(unsigned long long)fr->fr_hits);
-#else
- printf("%ld ", fr->fr_hits);
-#endif
- printfr(fr, ipftestioctl);
- }
+ dumprules(fg->fg_start);
}
printf("List of groups configured (set 1)\n");
for (i = 0; i < IPL_LOGSIZE; i++)
- for (fg = ipfgroups[i][1]; fg != NULL; fg = fg->fg_next) {
+ for (fg = softc->ipf_groups[i][1]; fg != NULL;
+ fg = fg->fg_next) {
printf("Dev.%d. Group %s Ref %d Flags %#x\n",
i, fg->fg_name, fg->fg_ref, fg->fg_flags);
- for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) {
+ dumprules(fg->fg_start);
+ }
+
+ printf("Rules configured (set 0, in)\n");
+ dumprules(softc->ipf_rules[0][0]);
+ printf("Rules configured (set 0, out)\n");
+ dumprules(softc->ipf_rules[1][0]);
+ printf("Rules configured (set 1, in)\n");
+ dumprules(softc->ipf_rules[0][1]);
+ printf("Rules configured (set 1, out)\n");
+ dumprules(softc->ipf_rules[1][1]);
+
+ printf("Accounting rules configured (set 0, in)\n");
+ dumprules(softc->ipf_acct[0][0]);
+ printf("Accounting rules configured (set 0, out)\n");
+ dumprules(softc->ipf_acct[0][1]);
+ printf("Accounting rules configured (set 1, in)\n");
+ dumprules(softc->ipf_acct[1][0]);
+ printf("Accounting rules configured (set 1, out)\n");
+ dumprules(softc->ipf_acct[1][1]);
+}
+
+void dumprules(rulehead)
+ frentry_t *rulehead;
+{
+ frentry_t *fr;
+
+ for (fr = rulehead; fr != NULL; fr = fr->fr_next) {
#ifdef USE_QUAD_T
- printf("%qu ",(unsigned long long)fr->fr_hits);
+ printf("%"PRIu64" ",(unsigned long long)fr->fr_hits);
#else
- printf("%ld ", fr->fr_hits);
+ printf("%ld ", fr->fr_hits);
#endif
- printfr(fr, ipftestioctl);
- }
- }
+ printfr(fr, ipftestioctl);
+ }
}
void drain_log(filename)
-char *filename;
+ char *filename;
{
char buffer[DEFAULT_IPFLOGSIZE];
struct iovec iov;
@@ -753,7 +788,7 @@ char *filename;
uio.uio_resid = iov.iov_len;
resid = uio.uio_resid;
- if (ipflog_read(i, &uio) == 0) {
+ if (ipf_log_read(softc, i, &uio) == 0) {
/*
* If nothing was read then break out.
*/
@@ -769,18 +804,38 @@ char *filename;
void fixv4sums(m, ip)
-mb_t *m;
-ip_t *ip;
+ mb_t *m;
+ ip_t *ip;
{
- u_char *csump, *hdr;
+ u_char *csump, *hdr, p;
+ fr_info_t tmp;
+ int len;
- ip->ip_sum = 0;
- ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2);
+ p = 0;
+ len = 0;
+ bzero((char *)&tmp, sizeof(tmp));
csump = (u_char *)ip;
- csump += IP_HL(ip) << 2;
+ if (IP_V(ip) == 4) {
+ ip->ip_sum = 0;
+ ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2);
+ tmp.fin_hlen = IP_HL(ip) << 2;
+ csump += IP_HL(ip) << 2;
+ p = ip->ip_p;
+ len = ntohs(ip->ip_len);
+#ifdef USE_INET6
+ } else if (IP_V(ip) == 6) {
+ tmp.fin_hlen = sizeof(ip6_t);
+ csump += sizeof(ip6_t);
+ p = ((ip6_t *)ip)->ip6_nxt;
+ len = ntohs(((ip6_t *)ip)->ip6_plen);
+ len += sizeof(ip6_t);
+#endif
+ }
+ tmp.fin_plen = len;
+ tmp.fin_dlen = len - tmp.fin_hlen;
- switch (ip->ip_p)
+ switch (p)
{
case IPPROTO_TCP :
hdr = csump;
@@ -800,7 +855,12 @@ ip_t *ip;
break;
}
if (hdr != NULL) {
+ tmp.fin_m = m;
+ tmp.fin_mp = &m;
+ tmp.fin_dp = hdr;
+ tmp.fin_ip = ip;
+ tmp.fin_plen = len;
*csump = 0;
- *(u_short *)csump = fr_cksum(m, ip, ip->ip_p, hdr, ip->ip_len);
+ *(u_short *)csump = fr_cksum(&tmp, ip, p, hdr);
}
}
diff --git a/contrib/ipfilter/tools/ipmon.c b/contrib/ipfilter/tools/ipmon.c
index ceaed82cb4b3..1c52e7fd87ac 100644
--- a/contrib/ipfilter/tools/ipmon.c
+++ b/contrib/ipfilter/tools/ipmon.c
@@ -1,84 +1,22 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#ifndef SOLARIS
-#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun)
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#define _KERNEL
-#include <sys/uio.h>
-#undef _KERNEL
-#include <sys/socket.h>
+#include "ipf.h"
+#include "ipmon.h"
#include <sys/ioctl.h>
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <ctype.h>
#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#if !defined(__SVR4) && !defined(__svr4__)
-# if (__FreeBSD_version >= 300000)
-# include <sys/dirent.h>
-# else
-# include <sys/dir.h>
-# endif
-#else
-# include <sys/filio.h>
-# include <sys/byteorder.h>
-#endif
-#if !defined(__hpux) && (!defined(__SVR4) && !defined(__GNUC__))
-# include <strings.h>
-#endif
#include <signal.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <net/if.h>
-#include <netinet/ip.h>
-#if !defined(__hpux) && !defined(linux)
-# include <netinet/tcp_fsm.h>
-#endif
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#ifdef __hpux
-# undef NOERROR
-#endif
-#include <resolv.h>
-
-#if !defined(linux)
-# include <sys/protosw.h>
-# include <netinet/ip_var.h>
-#endif
-
-#include <netinet/tcp.h>
-#include <netinet/ip_icmp.h>
-
-#include <ctype.h>
-#include <syslog.h>
-
-#include "netinet/ip_compat.h"
-#include <netinet/tcpip.h>
-#include "netinet/ip_fil.h"
-#include "netinet/ip_nat.h"
-#include "netinet/ip_state.h"
-#include "netinet/ip_proxy.h"
-#include "ipmon.h"
#if !defined(lint)
static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.20 2007/09/20 12:51:56 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
@@ -89,12 +27,41 @@ extern char *sys_errlist[];
#define STRERROR(x) strerror(x)
#endif
+extern int optind;
+extern char *optarg;
+
+extern ipmon_saver_t executesaver;
+extern ipmon_saver_t filesaver;
+extern ipmon_saver_t nothingsaver;
+extern ipmon_saver_t snmpv1saver;
+extern ipmon_saver_t snmpv2saver;
+extern ipmon_saver_t syslogsaver;
+
struct flags {
int value;
char flag;
};
+typedef struct logsource {
+ int fd;
+ int logtype;
+ char *file;
+ int regular;
+ size_t size;
+} logsource_t;
+
+typedef struct config {
+ int opts;
+ int maxfd;
+ logsource_t logsrc[3];
+ fd_set fdmr;
+ FILE *blog;
+ char *bfile;
+ FILE *log;
+ char *file;
+ char *cfile;
+} config_t;
typedef struct icmp_subtype {
int ist_val;
@@ -124,6 +91,28 @@ struct flags tcpfl[] = {
{ 0, '\0' }
};
+char *reasons[] = {
+ "filter-rule",
+ "log-or-block_1",
+ "pps-rate",
+ "jumbogram",
+ "makefrip-fail",
+ "state_add-fail",
+ "updateipid-fail",
+ "log-or-block_2",
+ "decap-fail",
+ "auth_new-fail",
+ "auth_captured",
+ "coalesce-fail",
+ "pullup-fail",
+ "auth-feedback",
+ "bad-frag",
+ "natv4_out-fail",
+ "natv4_in-fail",
+ "natv6_out-fail",
+ "natv6_in-fail",
+};
+
#ifdef MENTAT
static char *pidfile = "/etc/opt/ipf/ipmon.pid";
#else
@@ -135,18 +124,14 @@ static char *pidfile = "/etc/ipmon.pid";
#endif
static char line[2048];
-static int opts = 0;
-static char *logfile = NULL;
-static FILE *binarylog = NULL;
-static char *binarylogfile = NULL;
static int donehup = 0;
static void usage __P((char *));
static void handlehup __P((int));
static void flushlogs __P((char *, FILE *));
-static void print_log __P((int, FILE *, char *, int));
-static void print_ipflog __P((FILE *, char *, int));
-static void print_natlog __P((FILE *, char *, int));
-static void print_statelog __P((FILE *, char *, int));
+static void print_log __P((config_t *, logsource_t *, char *, int));
+static void print_ipflog __P((config_t *, char *, int));
+static void print_natlog __P((config_t *, char *, int));
+static void print_statelog __P((config_t *, char *, int));
static int read_log __P((int, int *, char *, int));
static void write_pid __P((char *));
static char *icmpname __P((u_int, u_int));
@@ -159,39 +144,30 @@ static struct tm *get_tm __P((u_32_t));
static struct tm *get_tm __P((time_t));
#endif
-char *hostname __P((int, int, u_32_t *));
-char *portname __P((int, char *, u_int));
+char *portlocalname __P((int, char *, u_int));
int main __P((int, char *[]));
static void logopts __P((int, char *));
static void init_tabs __P((void));
-static char *getproto __P((u_int));
+static char *getlocalproto __P((u_int));
+static void openlogs __P((config_t *conf));
+static int read_loginfo __P((config_t *conf));
+static void initconfig __P((config_t *conf));
static char **protocols = NULL;
static char **udp_ports = NULL;
static char **tcp_ports = NULL;
-static char *conf_file = NULL;
-#define OPT_SYSLOG 0x001
-#define OPT_RESOLVE 0x002
-#define OPT_HEXBODY 0x004
-#define OPT_VERBOSE 0x008
-#define OPT_HEXHDR 0x010
-#define OPT_TAIL 0x020
-#define OPT_NAT 0x080
-#define OPT_STATE 0x100
-#define OPT_FILTER 0x200
-#define OPT_PORTNUM 0x400
-#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER)
-#define OPT_LOGBODY 0x800
-
-#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b))
+#define HOSTNAMEV4(b) hostname(AF_INET, (u_32_t *)&(b))
#ifndef LOGFAC
#define LOGFAC LOG_LOCAL0
#endif
int logfac = LOGFAC;
+int ipmonopts = 0;
+int opts = OPT_NORESOLVE;
+int use_inet6 = 0;
static icmp_subtype_t icmpunreachnames[] = {
@@ -233,7 +209,7 @@ static icmp_subtype_t paramnames[] = {
{ -2, NULL }
};
-static icmp_type_t icmptypes[] = {
+static icmp_type_t icmptypes4[] = {
{ ICMP_ECHOREPLY, NULL, 0, "echoreply" },
{ -1, NULL, 0, NULL },
{ -1, NULL, 0, NULL },
@@ -338,9 +314,9 @@ static icmp_type_t icmptypes6[] = {
};
static icmp_subtype_t *find_icmpsubtype(type, table, tablesz)
-int type;
-icmp_subtype_t *table;
-size_t tablesz;
+ int type;
+ icmp_subtype_t *table;
+ size_t tablesz;
{
icmp_subtype_t *ist;
int i;
@@ -363,9 +339,9 @@ size_t tablesz;
static icmp_type_t *find_icmptype(type, table, tablesz)
-int type;
-icmp_type_t *table;
-size_t tablesz;
+ int type;
+ icmp_type_t *table;
+ size_t tablesz;
{
icmp_type_t *it;
int i;
@@ -388,7 +364,7 @@ size_t tablesz;
static void handlehup(sig)
-int sig;
+ int sig;
{
signal(SIGHUP, handlehup);
donehup = 1;
@@ -421,12 +397,12 @@ static void init_tabs()
p->p_name != NULL && protocols[p->p_proto] == NULL)
protocols[p->p_proto] = strdup(p->p_name);
endprotoent();
-#if defined(_AIX51)
if (protocols[0])
free(protocols[0]);
+ protocols[0] = strdup("ip");
+#if defined(_AIX51)
if (protocols[252])
free(protocols[252]);
- protocols[0] = "ip";
protocols[252] = NULL;
#endif
}
@@ -480,8 +456,8 @@ static void init_tabs()
}
-static char *getproto(p)
-u_int p;
+static char *getlocalproto(p)
+ u_int p;
{
static char pnum[4];
char *s;
@@ -497,11 +473,14 @@ u_int p;
static int read_log(fd, lenp, buf, bufsize)
-int fd, bufsize, *lenp;
-char *buf;
+ int fd, bufsize, *lenp;
+ char *buf;
{
int nr;
+ if (bufsize > IPFILTER_LOGSIZE)
+ bufsize = IPFILTER_LOGSIZE;
+
nr = read(fd, buf, bufsize);
if (!nr)
return 2;
@@ -512,51 +491,18 @@ char *buf;
}
-char *hostname(res, v, ip)
-int res, v;
-u_32_t *ip;
+char *portlocalname(res, proto, port)
+ int res;
+ char *proto;
+ u_int port;
{
-# define MAX_INETA 16
- static char hname[MAXHOSTNAMELEN + MAX_INETA + 3];
-#ifdef USE_INET6
- static char hostbuf[MAXHOSTNAMELEN+1];
-#endif
- struct hostent *hp;
- struct in_addr ipa;
-
- if (v == 4) {
- ipa.s_addr = *ip;
- if (!res)
- return inet_ntoa(ipa);
- hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET);
- if (!hp)
- return inet_ntoa(ipa);
- sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name,
- inet_ntoa(ipa));
- return hname;
- }
-#ifdef USE_INET6
- (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1);
- hostbuf[MAXHOSTNAMELEN] = '\0';
- return hostbuf;
-#else
- return "IPv6";
-#endif
-}
-
-
-char *portname(res, proto, port)
-int res;
-char *proto;
-u_int port;
-{
- static char pname[8];
- char *s;
+ static char pname[8];
+ char *s;
port = ntohs(port);
port &= 0xffff;
- (void) sprintf(pname, "%u", port);
- if (!res || (opts & OPT_PORTNUM))
+ sprintf(pname, "%u", port);
+ if (!res || (ipmonopts & IPMON_PORTNUM))
return pname;
s = NULL;
if (!strcmp(proto, "tcp"))
@@ -569,9 +515,9 @@ u_int port;
}
-static char *icmpname(type, code)
-u_int type;
-u_int code;
+static char *icmpname(type, code)
+ u_int type;
+ u_int code;
{
static char name[80];
icmp_subtype_t *ist;
@@ -579,7 +525,7 @@ u_int code;
char *s;
s = NULL;
- it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it));
+ it = find_icmptype(type, icmptypes4, sizeof(icmptypes4) / sizeof(*it));
if (it != NULL)
s = it->it_name;
@@ -600,9 +546,9 @@ u_int code;
return name;
}
-static char *icmpname6(type, code)
-u_int type;
-u_int code;
+static char *icmpname6(type, code)
+ u_int type;
+ u_int code;
{
static char name[80];
icmp_subtype_t *ist;
@@ -632,11 +578,11 @@ u_int code;
}
-void dumphex(log, dopts, buf, len)
-FILE *log;
-int dopts;
-char *buf;
-int len;
+void dumphex(log, dopts, buf, len)
+ FILE *log;
+ int dopts;
+ char *buf;
+ int len;
{
char hline[80];
int i, j, k;
@@ -651,7 +597,7 @@ int len;
if (j && !(j & 0xf)) {
*t++ = '\n';
*t = '\0';
- if ((dopts & OPT_SYSLOG))
+ if ((dopts & IPMON_SYSLOG))
syslog(LOG_INFO, "%s", hline);
else if (log != NULL)
fputs(hline, log);
@@ -665,10 +611,10 @@ int len;
sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
- *t++ = (ISPRINT(*s) ? *s : '.');
+ *t++ = (isprint(*s) ? *s : '.');
s--;
}
-
+
if ((j + 1) & 0xf)
*t++ = ' ';;
}
@@ -683,11 +629,11 @@ int len;
t += 7;
s -= j & 0xf;
for (k = j & 0xf; k; k--, s++)
- *t++ = (ISPRINT(*s) ? *s : '.');
+ *t++ = (isprint(*s) ? *s : '.');
*t++ = '\n';
*t = '\0';
}
- if ((dopts & OPT_SYSLOG) != 0)
+ if ((dopts & IPMON_SYSLOG) != 0)
syslog(LOG_INFO, "%s", hline);
else if (log != NULL) {
fputs(hline, log);
@@ -696,11 +642,11 @@ int len;
}
-static struct tm *get_tm(sec)
+static struct tm *get_tm(sec)
#ifdef __hpux
-u_32_t sec;
+ u_32_t sec;
#else
-time_t sec;
+ time_t sec;
#endif
{
struct tm *tm;
@@ -711,23 +657,44 @@ time_t sec;
return tm;
}
-static void print_natlog(log, buf, blen)
-FILE *log;
-char *buf;
-int blen;
+static void print_natlog(conf, buf, blen)
+ config_t *conf;
+ char *buf;
+ int blen;
{
- struct natlog *nl;
- iplog_t *ipl = (iplog_t *)buf;
- char *t = line;
- struct tm *tm;
- int res, i, len;
- char *proto;
+ static u_32_t seqnum = 0;
+ int res, i, len, family;
+ struct natlog *nl;
+ struct tm *tm;
+ iplog_t *ipl;
+ char *proto;
+ int simple;
+ char *t;
+
+ t = line;
+ simple = 0;
+ ipl = (iplog_t *)buf;
+ if (ipl->ipl_seqnum != seqnum) {
+ if ((ipmonopts & IPMON_SYSLOG) != 0) {
+ syslog(LOG_WARNING,
+ "missed %u NAT log entries: %u %u",
+ ipl->ipl_seqnum - seqnum, seqnum,
+ ipl->ipl_seqnum);
+ } else {
+ (void) fprintf(conf->log,
+ "missed %u NAT log entries: %u %u\n",
+ ipl->ipl_seqnum - seqnum, seqnum,
+ ipl->ipl_seqnum);
+ }
+ }
+ seqnum = ipl->ipl_seqnum + ipl->ipl_count;
nl = (struct natlog *)((char *)ipl + sizeof(*ipl));
- res = (opts & OPT_RESOLVE) ? 1 : 0;
+ res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0;
tm = get_tm(ipl->ipl_sec);
len = sizeof(line);
- if (!(opts & OPT_SYSLOG)) {
+
+ if (!(ipmonopts & IPMON_SYSLOG)) {
(void) strftime(t, len, "%d/%m/%Y ", tm);
i = strlen(t);
len -= i;
@@ -735,81 +702,184 @@ int blen;
}
(void) strftime(t, len, "%T", tm);
t += strlen(t);
- (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1);
+ sprintf(t, ".%-.6ld @%hd ", (long)ipl->ipl_usec, nl->nl_rule + 1);
t += strlen(t);
- if (nl->nl_type == NL_NEWMAP)
- strcpy(t, "NAT:MAP ");
- else if (nl->nl_type == NL_NEWRDR)
- strcpy(t, "NAT:RDR ");
- else if (nl->nl_type == NL_FLUSH)
- strcpy(t, "NAT:FLUSH ");
- else if (nl->nl_type == NL_EXPIRE)
- strcpy(t, "NAT:EXPIRE ");
- else if (nl->nl_type == NL_NEWBIMAP)
- strcpy(t, "NAT:BIMAP ");
- else if (nl->nl_type == NL_NEWBLOCK)
- strcpy(t, "NAT:MAPBLOCK ");
- else if (nl->nl_type == NL_CLONE)
- strcpy(t, "NAT:CLONE ");
- else if (nl->nl_type == NL_DESTROY)
- strcpy(t, "NAT:DESTROY ");
- else
- sprintf(t, "Type: %d ", nl->nl_type);
+ switch (nl->nl_action)
+ {
+ case NL_NEW :
+ strcpy(t, "NAT:NEW");
+ break;
+
+ case NL_FLUSH :
+ strcpy(t, "NAT:FLUSH");
+ break;
+
+ case NL_CLONE :
+ strcpy(t, "NAT:CLONE");
+ break;
+
+ case NL_EXPIRE :
+ strcpy(t, "NAT:EXPIRE");
+ break;
+
+ case NL_DESTROY :
+ strcpy(t, "NAT:DESTROY");
+ break;
+
+ case NL_PURGE :
+ strcpy(t, "NAT:PURGE");
+ break;
+
+ default :
+ sprintf(t, "NAT:Action(%d)", nl->nl_action);
+ break;
+ }
t += strlen(t);
- proto = getproto(nl->nl_p);
- (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip),
- portname(res, proto, (u_int)nl->nl_inport));
+ switch (nl->nl_type)
+ {
+ case NAT_MAP :
+ strcpy(t, "-MAP ");
+ simple = 1;
+ break;
+
+ case NAT_REDIRECT :
+ strcpy(t, "-RDR ");
+ simple = 1;
+ break;
+
+ case NAT_BIMAP :
+ strcpy(t, "-BIMAP ");
+ simple = 1;
+ break;
+
+ case NAT_MAPBLK :
+ strcpy(t, "-MAPBLOCK ");
+ simple = 1;
+ break;
+
+ case NAT_REWRITE|NAT_MAP :
+ strcpy(t, "-RWR_MAP ");
+ break;
+
+ case NAT_REWRITE|NAT_REDIRECT :
+ strcpy(t, "-RWR_RDR ");
+ break;
+
+ case NAT_ENCAP|NAT_MAP :
+ strcpy(t, "-ENC_MAP ");
+ break;
+
+ case NAT_ENCAP|NAT_REDIRECT :
+ strcpy(t, "-ENC_RDR ");
+ break;
+
+ case NAT_DIVERTUDP|NAT_MAP :
+ strcpy(t, "-DIV_MAP ");
+ break;
+
+ case NAT_DIVERTUDP|NAT_REDIRECT :
+ strcpy(t, "-DIV_RDR ");
+ break;
+
+ default :
+ sprintf(t, "-Type(%d) ", nl->nl_type);
+ break;
+ }
t += strlen(t);
- (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip),
- portname(res, proto, (u_int)nl->nl_outport));
+
+ proto = getlocalproto(nl->nl_p[0]);
+
+ family = vtof(nl->nl_v[0]);
+
+ if (simple == 1) {
+ sprintf(t, "%s,%s <- -> ", hostname(family, nl->nl_osrcip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_osrcport));
+ t += strlen(t);
+ sprintf(t, "%s,%s ", hostname(family, nl->nl_nsrcip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_nsrcport));
+ t += strlen(t);
+ sprintf(t, "[%s,%s] ", hostname(family, nl->nl_odstip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_odstport));
+ } else {
+ sprintf(t, "%s,%s ", hostname(family, nl->nl_osrcip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_osrcport));
+ t += strlen(t);
+ sprintf(t, "%s,%s <- -> ", hostname(family, nl->nl_odstip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_odstport));
+ t += strlen(t);
+ sprintf(t, "%s,%s ", hostname(family, nl->nl_nsrcip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_nsrcport));
+ t += strlen(t);
+ sprintf(t, "%s,%s ", hostname(family, nl->nl_ndstip.i6),
+ portlocalname(res, proto, (u_int)nl->nl_ndstport));
+ }
t += strlen(t);
- (void) sprintf(t, "[%s,%s PR %s]", HOSTNAME_V4(res, nl->nl_origip),
- portname(res, proto, (u_int)nl->nl_origport),
- getproto(nl->nl_p));
+
+ strcpy(t, getlocalproto(nl->nl_p[0]));
t += strlen(t);
- if (nl->nl_type == NL_EXPIRE) {
+
+ if (nl->nl_action == NL_EXPIRE || nl->nl_action == NL_FLUSH) {
#ifdef USE_QUAD_T
- (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd",
- (long long)nl->nl_pkts[0],
- (long long)nl->nl_pkts[1],
- (long long)nl->nl_bytes[0],
- (long long)nl->nl_bytes[1]);
+# ifdef PRId64
+ sprintf(t, " Pkts %" PRId64 "/%" PRId64 " Bytes %" PRId64 "/%"
+ PRId64,
+# else
+ sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd",
+# endif
#else
- (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld",
+ sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld",
+#endif
nl->nl_pkts[0], nl->nl_pkts[1],
nl->nl_bytes[0], nl->nl_bytes[1]);
-#endif
t += strlen(t);
}
*t++ = '\n';
*t++ = '\0';
- if (opts & OPT_SYSLOG)
+ if (ipmonopts & IPMON_SYSLOG)
syslog(LOG_INFO, "%s", line);
- else if (log != NULL)
- (void) fprintf(log, "%s", line);
+ else if (conf->log != NULL)
+ (void) fprintf(conf->log, "%s", line);
}
-static void print_statelog(log, buf, blen)
-FILE *log;
-char *buf;
-int blen;
+static void print_statelog(conf, buf, blen)
+ config_t *conf;
+ char *buf;
+ int blen;
{
- struct ipslog *sl;
- iplog_t *ipl = (iplog_t *)buf;
- char *t = line, *proto;
- struct tm *tm;
- int res, i, len;
+ static u_32_t seqnum = 0;
+ int res, i, len, family;
+ struct ipslog *sl;
+ char *t, *proto;
+ struct tm *tm;
+ iplog_t *ipl;
+
+ t = line;
+ ipl = (iplog_t *)buf;
+ if (ipl->ipl_seqnum != seqnum) {
+ if ((ipmonopts & IPMON_SYSLOG) != 0) {
+ syslog(LOG_WARNING,
+ "missed %u state log entries: %u %u",
+ ipl->ipl_seqnum - seqnum, seqnum,
+ ipl->ipl_seqnum);
+ } else {
+ (void) fprintf(conf->log,
+ "missed %u state log entries: %u %u\n",
+ ipl->ipl_seqnum - seqnum, seqnum,
+ ipl->ipl_seqnum);
+ }
+ }
+ seqnum = ipl->ipl_seqnum + ipl->ipl_count;
sl = (struct ipslog *)((char *)ipl + sizeof(*ipl));
- res = (opts & OPT_RESOLVE) ? 1 : 0;
+ res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0;
tm = get_tm(ipl->ipl_sec);
len = sizeof(line);
- if (!(opts & OPT_SYSLOG)) {
+ if (!(ipmonopts & IPMON_SYSLOG)) {
(void) strftime(t, len, "%d/%m/%Y ", tm);
i = strlen(t);
len -= i;
@@ -817,9 +887,11 @@ int blen;
}
(void) strftime(t, len, "%T", tm);
t += strlen(t);
- (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec);
+ sprintf(t, ".%-.6ld ", (long)ipl->ipl_usec);
t += strlen(t);
+ family = vtof(sl->isl_v);
+
switch (sl->isl_type)
{
case ISL_NEW :
@@ -865,41 +937,37 @@ int blen;
}
t += strlen(t);
- proto = getproto(sl->isl_p);
+ proto = getlocalproto(sl->isl_p);
if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) {
- (void) sprintf(t, "%s,%s -> ",
- hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src),
- portname(res, proto, (u_int)sl->isl_sport));
+ sprintf(t, "%s,%s -> ",
+ hostname(family, (u_32_t *)&sl->isl_src),
+ portlocalname(res, proto, (u_int)sl->isl_sport));
t += strlen(t);
- (void) sprintf(t, "%s,%s PR %s",
- hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
- portname(res, proto, (u_int)sl->isl_dport), proto);
+ sprintf(t, "%s,%s PR %s",
+ hostname(family, (u_32_t *)&sl->isl_dst),
+ portlocalname(res, proto, (u_int)sl->isl_dport), proto);
} else if (sl->isl_p == IPPROTO_ICMP) {
- (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
- (u_32_t *)&sl->isl_src));
+ sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src));
t += strlen(t);
- (void) sprintf(t, "%s PR icmp %d",
- hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
+ sprintf(t, "%s PR icmp %d",
+ hostname(family, (u_32_t *)&sl->isl_dst),
sl->isl_itype);
} else if (sl->isl_p == IPPROTO_ICMPV6) {
- (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v,
- (u_32_t *)&sl->isl_src));
+ sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src));
t += strlen(t);
- (void) sprintf(t, "%s PR icmpv6 %d",
- hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
+ sprintf(t, "%s PR icmpv6 %d",
+ hostname(family, (u_32_t *)&sl->isl_dst),
sl->isl_itype);
} else {
- (void) sprintf(t, "%s -> ",
- hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src));
+ sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src));
t += strlen(t);
- (void) sprintf(t, "%s PR %s",
- hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst),
- proto);
+ sprintf(t, "%s PR %s",
+ hostname(family, (u_32_t *)&sl->isl_dst), proto);
}
t += strlen(t);
if (sl->isl_tag != FR_NOLOGTAG) {
- (void) sprintf(t, " tag %u", sl->isl_tag);
+ sprintf(t, " tag %u", sl->isl_tag);
t += strlen(t);
}
if (sl->isl_type != ISL_NEW) {
@@ -926,22 +994,26 @@ int blen;
*t++ = '\n';
*t++ = '\0';
- if (opts & OPT_SYSLOG)
+ if (ipmonopts & IPMON_SYSLOG)
syslog(LOG_INFO, "%s", line);
- else if (log != NULL)
- (void) fprintf(log, "%s", line);
+ else if (conf->log != NULL)
+ (void) fprintf(conf->log, "%s", line);
}
-static void print_log(logtype, log, buf, blen)
-FILE *log;
-char *buf;
-int logtype, blen;
+static void print_log(conf, log, buf, blen)
+ config_t *conf;
+ logsource_t *log;
+ char *buf;
+ int blen;
{
+ char *bp, *bpo;
iplog_t *ipl;
- char *bp = NULL, *bpo = NULL;
int psize;
+ bp = NULL;
+ bpo = NULL;
+
while (blen > 0) {
ipl = (iplog_t *)buf;
if ((u_long)ipl & (sizeof(long)-1)) {
@@ -961,22 +1033,22 @@ int logtype, blen;
if (psize > blen)
break;
- if (binarylog) {
- fwrite(buf, psize, 1, binarylog);
- fflush(binarylog);
+ if (conf->blog != NULL) {
+ fwrite(buf, psize, 1, conf->blog);
+ fflush(conf->blog);
}
- if (logtype == IPL_LOGIPF) {
+ if (log->logtype == IPL_LOGIPF) {
if (ipl->ipl_magic == IPL_MAGIC)
- print_ipflog(log, buf, psize);
+ print_ipflog(conf, buf, psize);
- } else if (logtype == IPL_LOGNAT) {
+ } else if (log->logtype == IPL_LOGNAT) {
if (ipl->ipl_magic == IPL_MAGIC_NAT)
- print_natlog(log, buf, psize);
+ print_natlog(conf, buf, psize);
- } else if (logtype == IPL_LOGSTATE) {
+ } else if (log->logtype == IPL_LOGSTATE) {
if (ipl->ipl_magic == IPL_MAGIC_STATE)
- print_statelog(log, buf, psize);
+ print_statelog(conf, buf, psize);
}
blen -= psize;
@@ -988,22 +1060,23 @@ int logtype, blen;
}
-static void print_ipflog(log, buf, blen)
-FILE *log;
-char *buf;
-int blen;
+static void print_ipflog(conf, buf, blen)
+ config_t *conf;
+ char *buf;
+ int blen;
{
- tcphdr_t *tp;
- struct icmp *ic;
- struct icmp *icmp;
- struct tm *tm;
- char *t, *proto;
- int i, v, lvl, res, len, off, plen, ipoff, defaction;
- ip_t *ipc, *ip;
- u_32_t *s, *d;
- u_short hl, p;
+ static u_32_t seqnum = 0;
+ int i, f, lvl, res, len, off, plen, ipoff, defaction;
+ struct icmp *icmp;
+ struct icmp *ic;
+ char *t, *proto;
+ ip_t *ipc, *ip;
+ struct tm *tm;
+ u_32_t *s, *d;
+ u_short hl, p;
ipflog_t *ipf;
- iplog_t *ipl;
+ iplog_t *ipl;
+ tcphdr_t *tp;
#ifdef USE_INET6
struct ip6_ext *ehp;
u_short ehl;
@@ -1012,16 +1085,31 @@ int blen;
#endif
ipl = (iplog_t *)buf;
+ if (ipl->ipl_seqnum != seqnum) {
+ if ((ipmonopts & IPMON_SYSLOG) != 0) {
+ syslog(LOG_WARNING,
+ "missed %u ipf log entries: %u %u",
+ ipl->ipl_seqnum - seqnum, seqnum,
+ ipl->ipl_seqnum);
+ } else {
+ (void) fprintf(conf->log,
+ "missed %u ipf log entries: %u %u\n",
+ ipl->ipl_seqnum - seqnum, seqnum,
+ ipl->ipl_seqnum);
+ }
+ }
+ seqnum = ipl->ipl_seqnum + ipl->ipl_count;
+
ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
ip = (ip_t *)((char *)ipf + sizeof(*ipf));
- v = IP_V(ip);
- res = (opts & OPT_RESOLVE) ? 1 : 0;
+ f = ipf->fl_family;
+ res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0;
t = line;
*t = '\0';
tm = get_tm(ipl->ipl_sec);
len = sizeof(line);
- if (!(opts & OPT_SYSLOG)) {
+ if (!(ipmonopts & IPMON_SYSLOG)) {
(void) strftime(t, len, "%d/%m/%Y ", tm);
i = strlen(t);
len -= i;
@@ -1029,10 +1117,10 @@ int blen;
}
(void) strftime(t, len, "%T", tm);
t += strlen(t);
- (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec);
+ sprintf(t, ".%-.6ld ", (long)ipl->ipl_usec);
t += strlen(t);
if (ipl->ipl_count > 1) {
- (void) sprintf(t, "%dx ", ipl->ipl_count);
+ sprintf(t, "%dx ", ipl->ipl_count);
t += strlen(t);
}
#if (defined(MENTAT) || \
@@ -1044,13 +1132,19 @@ int blen;
strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname));
ifname[sizeof(ipf->fl_ifname)] = '\0';
- (void) sprintf(t, "%s", ifname);
+ sprintf(t, "%s", ifname);
t += strlen(t);
# if defined(MENTAT) || defined(linux)
- if (ISALPHA(*(t - 1))) {
- sprintf(t, "%d", ipf->fl_unit);
- t += strlen(t);
- }
+# if defined(linux)
+ /*
+ * On Linux, the loopback interface is just "lo", not "lo0".
+ */
+ if (strcmp(ifname, "lo") != 0)
+# endif
+ if (ISALPHA(*(t - 1))) {
+ sprintf(t, "%d", ipf->fl_unit);
+ t += strlen(t);
+ }
# endif
}
#else
@@ -1059,7 +1153,7 @@ int blen;
break;
if (ipf->fl_ifname[len])
len++;
- (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
+ sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
t += strlen(t);
#endif
if ((ipf->fl_group[0] == (char)~0) && (ipf->fl_group[1] == '\0'))
@@ -1067,12 +1161,12 @@ int blen;
else if (ipf->fl_group[0] == '\0')
(void) strcpy(t, " @0:");
else
- (void) sprintf(t, " @%s:", ipf->fl_group);
+ sprintf(t, " @%s:", ipf->fl_group);
t += strlen(t);
if (ipf->fl_rule == 0xffffffff)
strcat(t, "-1 ");
else
- (void) sprintf(t, "%u ", ipf->fl_rule + 1);
+ sprintf(t, "%u ", ipf->fl_rule + 1);
t += strlen(t);
lvl = LOG_NOTICE;
@@ -1107,8 +1201,17 @@ int blen;
*t++ = ' ';
*t = '\0';
- if (v == 6) {
+ if (f == AF_INET) {
+ hl = IP_HL(ip) << 2;
+ ipoff = ntohs(ip->ip_off);
+ off = ipoff & IP_OFFMASK;
+ p = (u_short)ip->ip_p;
+ s = (u_32_t *)&ip->ip_src;
+ d = (u_32_t *)&ip->ip_dst;
+ plen = ntohs(ip->ip_len);
+ } else
#ifdef USE_INET6
+ if (f == AF_INET6) {
off = 0;
ipoff = 0;
hl = sizeof(ip6_t);
@@ -1140,32 +1243,22 @@ int blen;
break;
}
}
-#else
- sprintf(t, "ipv6");
- goto printipflog;
+ } else
#endif
- } else if (v == 4) {
- hl = IP_HL(ip) << 2;
- ipoff = ip->ip_off;
- off = ipoff & IP_OFFMASK;
- p = (u_short)ip->ip_p;
- s = (u_32_t *)&ip->ip_src;
- d = (u_32_t *)&ip->ip_dst;
- plen = ip->ip_len;
- } else {
+ {
goto printipflog;
}
- proto = getproto(p);
+ proto = getlocalproto(p);
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) {
tp = (tcphdr_t *)((char *)ip + hl);
if (!(ipf->fl_lflags & FI_SHORT)) {
- (void) sprintf(t, "%s,%s -> ", hostname(res, v, s),
- portname(res, proto, (u_int)tp->th_sport));
+ sprintf(t, "%s,%s -> ", hostname(f, s),
+ portlocalname(res, proto, (u_int)tp->th_sport));
t += strlen(t);
- (void) sprintf(t, "%s,%s PR %s len %hu %hu",
- hostname(res, v, d),
- portname(res, proto, (u_int)tp->th_dport),
+ sprintf(t, "%s,%s PR %s len %hu %hu",
+ hostname(f, d),
+ portlocalname(res, proto, (u_int)tp->th_dport),
proto, hl, plen);
t += strlen(t);
@@ -1175,8 +1268,8 @@ int blen;
for (i = 0; tcpfl[i].value; i++)
if (tp->th_flags & tcpfl[i].value)
*t++ = tcpfl[i].flag;
- if (opts & OPT_VERBOSE) {
- (void) sprintf(t, " %lu %lu %hu",
+ if (ipmonopts & IPMON_VERBOSE) {
+ sprintf(t, " %lu %lu %hu",
(u_long)(ntohl(tp->th_seq)),
(u_long)(ntohl(tp->th_ack)),
ntohs(tp->th_win));
@@ -1185,24 +1278,26 @@ int blen;
}
*t = '\0';
} else {
- (void) sprintf(t, "%s -> ", hostname(res, v, s));
+ sprintf(t, "%s -> ", hostname(f, s));
t += strlen(t);
- (void) sprintf(t, "%s PR %s len %hu %hu",
- hostname(res, v, d), proto, hl, plen);
+ sprintf(t, "%s PR %s len %hu %hu",
+ hostname(f, d), proto, hl, plen);
}
- } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) {
+#if defined(AF_INET6) && defined(IPPROTO_ICMPV6)
+ } else if ((p == IPPROTO_ICMPV6) && !off && (f == AF_INET6)) {
ic = (struct icmp *)((char *)ip + hl);
- (void) sprintf(t, "%s -> ", hostname(res, v, s));
+ sprintf(t, "%s -> ", hostname(f, s));
t += strlen(t);
- (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s",
- hostname(res, v, d), hl, plen,
+ sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s",
+ hostname(f, d), hl, plen,
icmpname6(ic->icmp_type, ic->icmp_code));
- } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) {
+#endif
+ } else if ((p == IPPROTO_ICMP) && !off && (f == AF_INET)) {
ic = (struct icmp *)((char *)ip + hl);
- (void) sprintf(t, "%s -> ", hostname(res, v, s));
+ sprintf(t, "%s -> ", hostname(f, s));
t += strlen(t);
- (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s",
- hostname(res, v, d), hl, plen,
+ sprintf(t, "%s PR icmp len %hu %hu icmp %s",
+ hostname(f, d), hl, plen,
icmpname(ic->icmp_type, ic->icmp_code));
if (ic->icmp_type == ICMP_UNREACH ||
ic->icmp_type == ICMP_SOURCEQUENCH ||
@@ -1218,21 +1313,21 @@ int blen;
if (i > 1500)
i = ipc->ip_len;
ipoff = ntohs(ipc->ip_off);
- proto = getproto(ipc->ip_p);
+ proto = getlocalproto(ipc->ip_p);
if (!(ipoff & IP_OFFMASK) &&
((ipc->ip_p == IPPROTO_TCP) ||
(ipc->ip_p == IPPROTO_UDP))) {
tp = (tcphdr_t *)((char *)ipc + hl);
t += strlen(t);
- (void) sprintf(t, " for %s,%s -",
- HOSTNAME_V4(res, ipc->ip_src),
- portname(res, proto,
+ sprintf(t, " for %s,%s -",
+ HOSTNAMEV4(ipc->ip_src),
+ portlocalname(res, proto,
(u_int)tp->th_sport));
t += strlen(t);
- (void) sprintf(t, " %s,%s PR %s len %hu %hu",
- HOSTNAME_V4(res, ipc->ip_dst),
- portname(res, proto,
+ sprintf(t, " %s,%s PR %s len %hu %hu",
+ HOSTNAMEV4(ipc->ip_dst),
+ portlocalname(res, proto,
(u_int)tp->th_dport),
proto, IP_HL(ipc) << 2, i);
} else if (!(ipoff & IP_OFFMASK) &&
@@ -1240,26 +1335,25 @@ int blen;
icmp = (icmphdr_t *)((char *)ipc + hl);
t += strlen(t);
- (void) sprintf(t, " for %s -",
- HOSTNAME_V4(res, ipc->ip_src));
+ sprintf(t, " for %s -",
+ HOSTNAMEV4(ipc->ip_src));
t += strlen(t);
- (void) sprintf(t,
+ sprintf(t,
" %s PR icmp len %hu %hu icmp %d/%d",
- HOSTNAME_V4(res, ipc->ip_dst),
+ HOSTNAMEV4(ipc->ip_dst),
IP_HL(ipc) << 2, i,
icmp->icmp_type, icmp->icmp_code);
} else {
t += strlen(t);
- (void) sprintf(t, " for %s -",
- HOSTNAME_V4(res, ipc->ip_src));
+ sprintf(t, " for %s -",
+ HOSTNAMEV4(ipc->ip_src));
t += strlen(t);
- (void) sprintf(t, " %s PR %s len %hu (%hu)",
- HOSTNAME_V4(res, ipc->ip_dst), proto,
+ sprintf(t, " %s PR %s len %hu (%hu)",
+ HOSTNAMEV4(ipc->ip_dst), proto,
IP_HL(ipc) << 2, i);
t += strlen(t);
if (ipoff & IP_OFFMASK) {
- (void) sprintf(t,
- "(frag %d:%hu@%hu%s%s)",
+ sprintf(t, "(frag %d:%hu@%hu%s%s)",
ntohs(ipc->ip_id),
i - (IP_HL(ipc) << 2),
(ipoff & IP_OFFMASK) << 3,
@@ -1270,13 +1364,13 @@ int blen;
}
} else {
- (void) sprintf(t, "%s -> ", hostname(res, v, s));
+ sprintf(t, "%s -> ", hostname(f, s));
t += strlen(t);
- (void) sprintf(t, "%s PR %s len %hu (%hu)",
- hostname(res, v, d), proto, hl, plen);
+ sprintf(t, "%s PR %s len %hu (%hu)",
+ hostname(f, d), proto, hl, plen);
t += strlen(t);
if (off & IP_OFFMASK)
- (void) sprintf(t, " (frag %d:%hu@%hu%s%s)",
+ sprintf(t, " (frag %d:%hu@%hu%s%s)",
ntohs(ip->ip_id),
plen - hl, (off & IP_OFFMASK) << 3,
ipoff & IP_MF ? "+" : "",
@@ -1347,32 +1441,43 @@ printipflog:
strcpy(t, " mbcast");
t += 7;
}
+ if (ipf->fl_breason != 0) {
+ strcpy(t, " reason:");
+ t += 8;
+ strcpy(t, reasons[ipf->fl_breason]);
+ t += strlen(reasons[ipf->fl_breason]);
+ }
*t++ = '\n';
*t++ = '\0';
defaction = 0;
- if (conf_file != NULL)
- defaction = check_action(buf, line, opts, lvl);
+ if (conf->cfile != NULL)
+ defaction = check_action(buf, line, ipmonopts, lvl);
+
if (defaction == 0) {
- if (opts & OPT_SYSLOG)
+ if (ipmonopts & IPMON_SYSLOG) {
syslog(lvl, "%s", line);
- else if (log != NULL)
- (void) fprintf(log, "%s", line);
+ } else if (conf->log != NULL) {
+ (void) fprintf(conf->log, "%s", line);
+ }
- if (opts & OPT_HEXHDR)
- dumphex(log, opts, buf,
+ if (ipmonopts & IPMON_HEXHDR) {
+ dumphex(conf->log, ipmonopts, buf,
sizeof(iplog_t) + sizeof(*ipf));
- if (opts & OPT_HEXBODY)
- dumphex(log, opts, (char *)ip,
+ }
+ if (ipmonopts & IPMON_HEXBODY) {
+ dumphex(conf->log, ipmonopts, (char *)ip,
ipf->fl_plen + ipf->fl_hlen);
- else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY))
- dumphex(log, opts, (char *)ip + ipf->fl_hlen,
+ } else if ((ipmonopts & IPMON_LOGBODY) &&
+ (ipf->fl_flags & FR_LOGBODY)) {
+ dumphex(conf->log, ipmonopts, (char *)ip + ipf->fl_hlen,
ipf->fl_plen);
+ }
}
}
static void usage(prog)
-char *prog;
+ char *prog;
{
fprintf(stderr, "%s: [-NFhstvxX] [-f <logfile>]\n", prog);
exit(1);
@@ -1380,7 +1485,7 @@ char *prog;
static void write_pid(file)
-char *file;
+ char *file;
{
FILE *fp = NULL;
int fd;
@@ -1400,8 +1505,8 @@ char *file;
static void flushlogs(file, log)
-char *file;
-FILE *log;
+ char *file;
+ FILE *log;
{
int fd, flushed = 0;
@@ -1416,11 +1521,11 @@ FILE *log;
flushed);
fflush(stdout);
} else
- perror("SIOCIPFFB");
+ ipferror(fd, "SIOCIPFFB");
(void) close(fd);
if (flushed) {
- if (opts & OPT_SYSLOG) {
+ if (ipmonopts & IPMON_SYSLOG) {
syslog(LOG_INFO, "%d bytes flushed from log\n",
flushed);
} else if ((log != stdout) && (log != NULL)) {
@@ -1431,8 +1536,8 @@ FILE *log;
static void logopts(turnon, options)
-int turnon;
-char *options;
+ int turnon;
+ char *options;
{
int flags = 0;
char *s;
@@ -1442,13 +1547,13 @@ char *options;
switch (*s)
{
case 'N' :
- flags |= OPT_NAT;
+ flags |= IPMON_NAT;
break;
case 'S' :
- flags |= OPT_STATE;
+ flags |= IPMON_STATE;
break;
case 'I' :
- flags |= OPT_FILTER;
+ flags |= IPMON_FILTER;
break;
default :
fprintf(stderr, "Unknown log option %c\n", *s);
@@ -1457,64 +1562,87 @@ char *options;
}
if (turnon)
- opts |= flags;
+ ipmonopts |= flags;
else
- opts &= ~(flags);
+ ipmonopts &= ~(flags);
+}
+
+static void initconfig(config_t *conf)
+{
+ int i;
+
+ memset(conf, 0, sizeof(*conf));
+
+ conf->log = stdout;
+ conf->maxfd = -1;
+
+ for (i = 0; i < 3; i++) {
+ conf->logsrc[i].fd = -1;
+ conf->logsrc[i].logtype = -1;
+ conf->logsrc[i].regular = -1;
+ }
+
+ conf->logsrc[0].file = IPL_NAME;
+ conf->logsrc[1].file = IPNAT_NAME;
+ conf->logsrc[2].file = IPSTATE_NAME;
+
+ add_doing(&executesaver);
+ add_doing(&snmpv1saver);
+ add_doing(&snmpv2saver);
+ add_doing(&syslogsaver);
+ add_doing(&filesaver);
+ add_doing(&nothingsaver);
}
int main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
- struct stat sb;
- FILE *log = stdout;
- FILE *fp;
- int fd[3], doread, n, i;
- int tr, nr, regular[3], c;
- int fdt[3], devices = 0, make_daemon = 0;
- char buf[DEFAULT_IPFLOGSIZE], *iplfile[3], *s;
- extern int optind;
- extern char *optarg;
+ int doread, c, make_daemon = 0;
+ char *prog;
+ config_t config;
+
+ prog = strrchr(argv[0], '/');
+ if (prog == NULL)
+ prog = argv[0];
+ else
+ prog++;
- fd[0] = fd[1] = fd[2] = -1;
- fdt[0] = fdt[1] = fdt[2] = -1;
- iplfile[0] = IPL_NAME;
- iplfile[1] = IPNAT_NAME;
- iplfile[2] = IPSTATE_NAME;
+ initconfig(&config);
while ((c = getopt(argc, argv,
"?abB:C:Df:FhL:nN:o:O:pP:sS:tvxX")) != -1)
switch (c)
{
case 'a' :
- opts |= OPT_LOGALL;
- fdt[0] = IPL_LOGIPF;
- fdt[1] = IPL_LOGNAT;
- fdt[2] = IPL_LOGSTATE;
+ ipmonopts |= IPMON_LOGALL;
+ config.logsrc[0].logtype = IPL_LOGIPF;
+ config.logsrc[1].logtype = IPL_LOGNAT;
+ config.logsrc[2].logtype = IPL_LOGSTATE;
break;
case 'b' :
- opts |= OPT_LOGBODY;
+ ipmonopts |= IPMON_LOGBODY;
break;
case 'B' :
- binarylogfile = optarg;
- binarylog = fopen(optarg, "a");
+ config.bfile = optarg;
+ config.blog = fopen(optarg, "a");
break;
case 'C' :
- conf_file = optarg;
+ config.cfile = optarg;
break;
case 'D' :
make_daemon = 1;
break;
case 'f' : case 'I' :
- opts |= OPT_FILTER;
- fdt[0] = IPL_LOGIPF;
- iplfile[0] = optarg;
+ ipmonopts |= IPMON_FILTER;
+ config.logsrc[0].logtype = IPL_LOGIPF;
+ config.logsrc[0].file = optarg;
break;
case 'F' :
- flushlogs(iplfile[0], log);
- flushlogs(iplfile[1], log);
- flushlogs(iplfile[2], log);
+ flushlogs(config.logsrc[0].file, config.log);
+ flushlogs(config.logsrc[1].file, config.log);
+ flushlogs(config.logsrc[2].file, config.log);
break;
case 'L' :
logfac = fac_findname(optarg);
@@ -1526,56 +1654,49 @@ char *argv[];
}
break;
case 'n' :
- opts |= OPT_RESOLVE;
+ ipmonopts |= IPMON_RESOLVE;
+ opts &= ~OPT_NORESOLVE;
break;
case 'N' :
- opts |= OPT_NAT;
- fdt[1] = IPL_LOGNAT;
- iplfile[1] = optarg;
+ ipmonopts |= IPMON_NAT;
+ config.logsrc[1].logtype = IPL_LOGNAT;
+ config.logsrc[1].file = optarg;
break;
case 'o' : case 'O' :
logopts(c == 'o', optarg);
- fdt[0] = fdt[1] = fdt[2] = -1;
- if (opts & OPT_FILTER)
- fdt[0] = IPL_LOGIPF;
- if (opts & OPT_NAT)
- fdt[1] = IPL_LOGNAT;
- if (opts & OPT_STATE)
- fdt[2] = IPL_LOGSTATE;
+ if (ipmonopts & IPMON_FILTER)
+ config.logsrc[0].logtype = IPL_LOGIPF;
+ if (ipmonopts & IPMON_NAT)
+ config.logsrc[1].logtype = IPL_LOGNAT;
+ if (ipmonopts & IPMON_STATE)
+ config.logsrc[2].logtype = IPL_LOGSTATE;
break;
case 'p' :
- opts |= OPT_PORTNUM;
+ ipmonopts |= IPMON_PORTNUM;
break;
case 'P' :
pidfile = optarg;
break;
case 's' :
- s = strrchr(argv[0], '/');
- if (s == NULL)
- s = argv[0];
- else
- s++;
- openlog(s, LOG_NDELAY|LOG_PID, logfac);
- s = NULL;
- opts |= OPT_SYSLOG;
- log = NULL;
+ ipmonopts |= IPMON_SYSLOG;
+ config.log = NULL;
break;
case 'S' :
- opts |= OPT_STATE;
- fdt[2] = IPL_LOGSTATE;
- iplfile[2] = optarg;
+ ipmonopts |= IPMON_STATE;
+ config.logsrc[2].logtype = IPL_LOGSTATE;
+ config.logsrc[2].file = optarg;
break;
case 't' :
- opts |= OPT_TAIL;
+ ipmonopts |= IPMON_TAIL;
break;
case 'v' :
- opts |= OPT_VERBOSE;
+ ipmonopts |= IPMON_VERBOSE;
break;
case 'x' :
- opts |= OPT_HEXBODY;
+ ipmonopts |= IPMON_HEXBODY;
break;
case 'X' :
- opts |= OPT_HEXHDR;
+ ipmonopts |= IPMON_HEXHDR;
break;
default :
case 'h' :
@@ -1583,69 +1704,62 @@ char *argv[];
usage(argv[0]);
}
+ if (ipmonopts & IPMON_SYSLOG)
+ openlog(prog, LOG_NDELAY|LOG_PID, logfac);
+
init_tabs();
- if (conf_file)
- if (load_config(conf_file) == -1)
+ if (config.cfile)
+ if (load_config(config.cfile) == -1) {
+ unload_config();
exit(1);
+ }
/*
* Default action is to only open the filter log file.
*/
- if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1))
- fdt[0] = IPL_LOGIPF;
+ if ((config.logsrc[0].logtype == -1) &&
+ (config.logsrc[0].logtype == -1) &&
+ (config.logsrc[0].logtype == -1))
+ config.logsrc[0].logtype = IPL_LOGIPF;
- for (i = 0; i < 3; i++) {
- if (fdt[i] == -1)
- continue;
- if (!strcmp(iplfile[i], "-"))
- fd[i] = 0;
- else {
- if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) {
- (void) fprintf(stderr,
- "%s: open: %s\n", iplfile[i],
- STRERROR(errno));
- exit(1);
- /* NOTREACHED */
- }
- if (fstat(fd[i], &sb) == -1) {
- (void) fprintf(stderr, "%d: fstat: %s\n",
- fd[i], STRERROR(errno));
- exit(1);
- /* NOTREACHED */
- }
- if (!(regular[i] = !S_ISCHR(sb.st_mode)))
- devices++;
- }
- }
+ openlogs(&config);
- if (!(opts & OPT_SYSLOG)) {
- logfile = argv[optind];
- log = logfile ? fopen(logfile, "a") : stdout;
- if (log == NULL) {
+ if (!(ipmonopts & IPMON_SYSLOG)) {
+ config.file = argv[optind];
+ config.log = config.file ? fopen(config.file, "a") : stdout;
+ if (config.log == NULL) {
(void) fprintf(stderr, "%s: fopen: %s\n",
argv[optind], STRERROR(errno));
exit(1);
/* NOTREACHED */
}
- setvbuf(log, NULL, _IONBF, 0);
- } else
- log = NULL;
+ setvbuf(config.log, NULL, _IONBF, 0);
+ } else {
+ config.log = NULL;
+ }
- if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) {
+ if (make_daemon &&
+ ((config.log != stdout) || (ipmonopts & IPMON_SYSLOG))) {
#if BSD >= 199306
- daemon(0, !(opts & OPT_SYSLOG));
+ daemon(0, !(ipmonopts & IPMON_SYSLOG));
#else
int pid;
- if ((pid = fork()) > 0)
- exit(0);
- if (pid < 0) {
+
+ switch (fork())
+ {
+ case -1 :
(void) fprintf(stderr, "%s: fork() failed: %s\n",
argv[0], STRERROR(errno));
exit(1);
/* NOTREACHED */
+ case 0 :
+ break;
+ default :
+ exit(0);
}
+
setsid();
- if ((opts & OPT_SYSLOG))
+ if ((ipmonopts & IPMON_SYSLOG))
close(2);
#endif /* !BSD */
close(0);
@@ -1655,80 +1769,142 @@ char *argv[];
signal(SIGHUP, handlehup);
- for (doread = 1; doread; ) {
- nr = 0;
+ for (doread = 1; doread; )
+ doread = read_loginfo(&config);
- for (i = 0; i < 3; i++) {
- tr = 0;
- if (fdt[i] == -1)
- continue;
- if (!regular[i]) {
- if (ioctl(fd[i], FIONREAD, &tr) == -1) {
- if (opts & OPT_SYSLOG)
- syslog(LOG_CRIT,
- "ioctl(FIONREAD): %m");
- else
- perror("ioctl(FIONREAD)");
- exit(1);
- /* NOTREACHED */
- }
- } else {
- tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size);
- if (!tr && !(opts & OPT_TAIL))
- doread = 0;
+ unload_config();
+
+ return(0);
+ /* NOTREACHED */
+}
+
+
+static void openlogs(config_t *conf)
+{
+ logsource_t *l;
+ struct stat sb;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ l = &conf->logsrc[i];
+ if (l->logtype == -1)
+ continue;
+ if (!strcmp(l->file, "-"))
+ l->fd = 0;
+ else {
+ if ((l->fd= open(l->file, O_RDONLY)) == -1) {
+ (void) fprintf(stderr,
+ "%s: open: %s\n", l->file,
+ STRERROR(errno));
+ exit(1);
+ /* NOTREACHED */
}
- if (!tr)
- continue;
- nr += tr;
- n = 0;
- tr = read_log(fd[i], &n, buf, sizeof(buf));
- if (donehup) {
- if (logfile && (fp = fopen(logfile, "a"))) {
- fclose(log);
- log = fp;
- }
- if (binarylogfile &&
- (fp = fopen(binarylogfile, "a"))) {
- fclose(binarylog);
- binarylog = fp;
+ if (fstat(l->fd, &sb) == -1) {
+ (void) fprintf(stderr, "%d: fstat: %s\n",
+ l->fd, STRERROR(errno));
+ exit(1);
+ /* NOTREACHED */
+ }
+
+ l->regular = !S_ISCHR(sb.st_mode);
+ if (l->regular)
+ l->size = sb.st_size;
+
+ FD_SET(l->fd, &conf->fdmr);
+ if (l->fd > conf->maxfd)
+ conf->maxfd = l->fd;
+ }
+ }
+}
+
+
+static int read_loginfo(config_t *conf)
+{
+ iplog_t buf[DEFAULT_IPFLOGSIZE/sizeof(iplog_t)+1];
+ int n, tr, nr, i;
+ logsource_t *l;
+ fd_set fdr;
+
+ fdr = conf->fdmr;
+
+ n = select(conf->maxfd + 1, &fdr, NULL, NULL, NULL);
+ if (n == 0)
+ return 1;
+ if (n == -1) {
+ if (errno == EINTR)
+ return 1;
+ return -1;
+ }
+
+ for (i = 0, nr = 0; i < 3; i++) {
+ l = &conf->logsrc[i];
+
+ if ((l->logtype == -1) || !FD_ISSET(l->fd, &fdr))
+ continue;
+
+ tr = 0;
+ if (l->regular) {
+ tr = (lseek(l->fd, 0, SEEK_CUR) < l->size);
+ if (!tr && !(ipmonopts & IPMON_TAIL))
+ return 0;
+ }
+
+ n = 0;
+ tr = read_log(l->fd, &n, (char *)buf, sizeof(buf));
+ if (donehup) {
+ if (conf->file != NULL) {
+ if (conf->log != NULL) {
+ fclose(conf->log);
+ conf->log = NULL;
}
- init_tabs();
- if (conf_file != NULL)
- load_config(conf_file);
- donehup = 0;
+ conf->log = fopen(conf->file, "a");
}
- switch (tr)
- {
- case -1 :
- if (opts & OPT_SYSLOG)
- syslog(LOG_CRIT, "read: %m\n");
- else
- perror("read");
- doread = 0;
- break;
- case 1 :
- if (opts & OPT_SYSLOG)
- syslog(LOG_CRIT, "aborting logging\n");
- else if (log != NULL)
- fprintf(log, "aborting logging\n");
- doread = 0;
- break;
- case 2 :
- break;
- case 0 :
- if (n > 0) {
- print_log(fdt[i], log, buf, n);
- if (!(opts & OPT_SYSLOG))
- fflush(log);
+ if (conf->bfile != NULL) {
+ if (conf->blog != NULL) {
+ fclose(conf->blog);
+ conf->blog = NULL;
}
- break;
+ conf->blog = fopen(conf->bfile, "a");
}
+
+ init_tabs();
+ if (conf->cfile != NULL)
+ load_config(conf->cfile);
+ donehup = 0;
+ }
+
+ switch (tr)
+ {
+ case -1 :
+ if (ipmonopts & IPMON_SYSLOG)
+ syslog(LOG_CRIT, "read: %m\n");
+ else {
+ ipferror(l->fd, "read");
+ }
+ return 0;
+ case 1 :
+ if (ipmonopts & IPMON_SYSLOG)
+ syslog(LOG_CRIT, "aborting logging\n");
+ else if (conf->log != NULL)
+ fprintf(conf->log, "aborting logging\n");
+ return 0;
+ case 2 :
+ break;
+ case 0 :
+ nr += tr;
+ if (n > 0) {
+ print_log(conf, l, (char *)buf, n);
+ if (!(ipmonopts & IPMON_SYSLOG))
+ fflush(conf->log);
+ }
+ break;
}
- if (!nr && ((opts & OPT_TAIL) || devices))
- sleep(1);
}
- return(0);
- /* NOTREACHED */
+
+ if (!nr && (ipmonopts & IPMON_TAIL))
+ sleep(1);
+
+ return 1;
}
diff --git a/contrib/ipfilter/tools/ipmon_y.y b/contrib/ipfilter/tools/ipmon_y.y
index 98042d880222..f14180d6a9e9 100644
--- a/contrib/ipfilter/tools/ipmon_y.y
+++ b/contrib/ipfilter/tools/ipmon_y.y
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2004 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -13,6 +13,8 @@
#include "ipmon_l.h"
#include "ipmon.h"
+#include <dlfcn.h>
+
#define YYDEBUG 1
extern void yyerror __P((char *));
@@ -21,69 +23,88 @@ extern int yylex __P((void));
extern int yydebug;
extern FILE *yyin;
extern int yylineNum;
+extern int ipmonopts;
-typedef struct opt {
- struct opt *o_next;
+typedef struct opt_s {
+ struct opt_s *o_next;
int o_line;
int o_type;
int o_num;
char *o_str;
struct in_addr o_ip;
+ int o_logfac;
+ int o_logpri;
} opt_t;
-static void build_action __P((struct opt *));
+static void build_action __P((opt_t *, ipmon_doing_t *));
static opt_t *new_opt __P((int));
static void free_action __P((ipmon_action_t *));
+static void print_action __P((ipmon_action_t *));
+static int find_doing __P((char *));
+static ipmon_doing_t *build_doing __P((char *, char *));
+static void print_match __P((ipmon_action_t *));
+static int install_saver __P((char *, char *));
static ipmon_action_t *alist = NULL;
+
+ipmon_saver_int_t *saverlist = NULL;
%}
%union {
char *str;
u_32_t num;
struct in_addr addr;
- struct opt *opt;
+ struct opt_s *opt;
union i6addr ip6;
+ struct ipmon_doing_s *ipmd;
}
%token <num> YY_NUMBER YY_HEX
%token <str> YY_STR
%token <ip6> YY_IPV6
-%token YY_COMMENT
+%token YY_COMMENT
%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
%token YY_RANGE_OUT YY_RANGE_IN
%token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT
-%token IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT
+%token IPM_EVERY IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT IPM_LOADACTION
%token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE
%token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH
-%token IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT
+%token IPM_DO IPM_DOING IPM_TYPE IPM_NAT
%token IPM_STATE IPM_NATTAG IPM_IPF
%type <addr> ipv4
-%type <opt> direction dstip dstport every execute group interface
+%type <opt> direction dstip dstport every group interface
%type <opt> protocol result rule srcip srcport logtag matching
-%type <opt> matchopt nattag type doopt doing save syslog nothing
-%type <num> saveopts saveopt typeopt
+%type <opt> matchopt nattag type
+%type <num> typeopt
+%type <ipmd> doopt doing
%%
-file: line
- | assign
- | file line
- | file assign
+file: action
+ | file action
;
-line: IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';'
- { build_action($3); resetlexer(); }
+action: line ';'
+ | assign ';'
| IPM_COMMENT
| YY_COMMENT
;
-assign: YY_STR assigning YY_STR ';' { set_variable($1, $3);
+line: IPM_MATCH '{' matching ';' '}' IPM_DO '{' doing ';' '}'
+ { build_action($3, $8);
+ resetlexer();
+ }
+ | IPM_LOADACTION YY_STR YY_STR { if (install_saver($2, $3))
+ yyerror("install saver");
+ }
+ ;
+
+assign: YY_STR assigning YY_STR { set_variable($1, $3);
resetlexer();
free($1);
free($3);
yyvarnext = 0;
- }
+ }
;
assigning:
@@ -114,14 +135,20 @@ matchopt:
doing:
doopt { $$ = $1; }
- | doopt ',' doing { $1->o_next = $3; $$ = $1; }
+ | doopt ',' doing { $1->ipmd_next = $3; $$ = $1; }
;
doopt:
- execute { $$ = $1; }
- | save { $$ = $1; }
- | syslog { $$ = $1; }
- | nothing { $$ = $1; }
+ YY_STR { if (find_doing($1) != IPM_DOING)
+ yyerror("unknown action");
+ }
+ '(' YY_STR ')' { $$ = build_doing($1, $4);
+ if ($$ == NULL)
+ yyerror("action building");
+ }
+ | YY_STR { if (find_doing($1) == IPM_DOING)
+ $$ = build_doing($1, NULL);
+ }
;
direction:
@@ -211,31 +238,7 @@ typeopt:
| IPM_STATE { $$ = IPL_MAGIC_STATE; }
;
-execute:
- IPM_EXECUTE YY_STR { $$ = new_opt(IPM_EXECUTE);
- $$->o_str = $2; }
- ;
-
-save: IPM_SAVE saveopts YY_STR { $$ = new_opt(IPM_SAVE);
- $$->o_num = $2;
- $$->o_str = $3; }
- ;
-
-saveopts: { $$ = 0; }
- | saveopt { $$ = $1; }
- | saveopt ',' saveopts { $$ = $1 | $3; }
- ;
-
-saveopt:
- IPM_RAW { $$ = IPMDO_SAVERAW; }
- ;
-
-syslog: IPM_SYSLOG { $$ = new_opt(IPM_SYSLOG); }
- ;
-nothing:
- IPM_NOTHING { $$ = 0; }
- ;
ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
@@ -253,30 +256,27 @@ static struct wordtab yywords[] = {
{ "dstip", IPM_DSTIP },
{ "dstport", IPM_DSTPORT },
{ "every", IPM_EVERY },
- { "execute", IPM_EXECUTE },
{ "group", IPM_GROUP },
{ "in", IPM_IN },
{ "interface", IPM_INTERFACE },
{ "ipf", IPM_IPF },
+ { "load_action",IPM_LOADACTION },
{ "logtag", IPM_LOGTAG },
{ "match", IPM_MATCH },
{ "nat", IPM_NAT },
{ "nattag", IPM_NATTAG },
{ "no", IPM_NO },
- { "nothing", IPM_NOTHING },
{ "out", IPM_OUT },
{ "packet", IPM_PACKET },
{ "packets", IPM_PACKETS },
{ "protocol", IPM_PROTOCOL },
{ "result", IPM_RESULT },
{ "rule", IPM_RULE },
- { "save", IPM_SAVE },
{ "second", IPM_SECOND },
{ "seconds", IPM_SECONDS },
{ "srcip", IPM_SRCIP },
{ "srcport", IPM_SRCPORT },
{ "state", IPM_STATE },
- { "syslog", IPM_SYSLOG },
{ "with", IPM_WITH },
{ NULL, 0 }
};
@@ -301,31 +301,33 @@ static int macflags[17][2] = {
{ 0, 0 }
};
-static opt_t *new_opt(type)
-int type;
+static opt_t *
+new_opt(type)
+ int type;
{
opt_t *o;
- o = (opt_t *)malloc(sizeof(*o));
+ o = (opt_t *)calloc(1, sizeof(*o));
o->o_type = type;
o->o_line = yylineNum;
- o->o_num = 0;
- o->o_str = (char *)0;
- o->o_next = NULL;
+ o->o_logfac = -1;
+ o->o_logpri = -1;
return o;
}
-static void build_action(olist)
-opt_t *olist;
+static void
+build_action(olist, todo)
+ opt_t *olist;
+ ipmon_doing_t *todo;
{
ipmon_action_t *a;
opt_t *o;
- char c;
int i;
a = (ipmon_action_t *)calloc(1, sizeof(*a));
if (a == NULL)
return;
+
while ((o = olist) != NULL) {
/*
* Check to see if the same comparator is being used more than
@@ -358,24 +360,11 @@ opt_t *olist;
case IPM_DSTPORT :
a->ac_dport = htons(o->o_num);
break;
- case IPM_EXECUTE :
- a->ac_exec = o->o_str;
- c = *o->o_str;
- if (c== '"'|| c == '\'') {
- if (o->o_str[strlen(o->o_str) - 1] == c) {
- a->ac_run = strdup(o->o_str + 1);
- a->ac_run[strlen(a->ac_run) - 1] ='\0';
- } else
- a->ac_run = o->o_str;
- } else
- a->ac_run = o->o_str;
- o->o_str = NULL;
- break;
case IPM_INTERFACE :
a->ac_iface = o->o_str;
o->o_str = NULL;
break;
- case IPM_GROUP :
+ case IPM_GROUP :
if (o->o_str != NULL)
strncpy(a->ac_group, o->o_str, FR_GROUPLEN);
else
@@ -416,24 +405,6 @@ opt_t *olist;
case IPM_SRCPORT :
a->ac_sport = htons(o->o_num);
break;
- case IPM_SAVE :
- if (a->ac_savefile != NULL) {
- fprintf(stderr, "%s redfined on line %d\n",
- yykeytostr(o->o_type), yylineNum);
- break;
- }
- a->ac_savefile = strdup(o->o_str);
- a->ac_savefp = fopen(o->o_str, "a");
- a->ac_dflag |= o->o_num & IPMDO_SAVERAW;
- break;
- case IPM_SYSLOG :
- if (a->ac_syslog != 0) {
- fprintf(stderr, "%s redfined on line %d\n",
- yykeytostr(o->o_type), yylineNum);
- break;
- }
- a->ac_syslog = 1;
- break;
case IPM_TYPE :
a->ac_type = o->o_num;
break;
@@ -448,17 +419,25 @@ opt_t *olist;
free(o->o_str);
free(o);
}
+
+ a->ac_doing = todo;
a->ac_next = alist;
alist = a;
+
+ if (ipmonopts & IPMON_VERBOSE)
+ print_action(a);
}
-int check_action(buf, log, opts, lvl)
-char *buf, *log;
-int opts, lvl;
+int
+check_action(buf, log, opts, lvl)
+ char *buf, *log;
+ int opts, lvl;
{
ipmon_action_t *a;
struct timeval tv;
+ ipmon_doing_t *d;
+ ipmon_msg_t msg;
ipflog_t *ipf;
tcphdr_t *tcp;
iplog_t *ipl;
@@ -472,19 +451,33 @@ int opts, lvl;
ip = (ip_t *)(ipf + 1);
tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
+ msg.imm_data = ipl;
+ msg.imm_dsize = ipl->ipl_dsize;
+ msg.imm_when = ipl->ipl_time.tv_sec;
+ msg.imm_msg = log;
+ msg.imm_msglen = strlen(log);
+ msg.imm_loglevel = lvl;
+
for (a = alist; a != NULL; a = a->ac_next) {
+ verbose(0, "== checking config rule\n");
if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
if (a->ac_direction == IPM_IN) {
- if ((ipf->fl_flags & FR_INQUE) == 0)
+ if ((ipf->fl_flags & FR_INQUE) == 0) {
+ verbose(8, "-- direction not in\n");
continue;
+ }
} else if (a->ac_direction == IPM_OUT) {
- if ((ipf->fl_flags & FR_OUTQUE) == 0)
+ if ((ipf->fl_flags & FR_OUTQUE) == 0) {
+ verbose(8, "-- direction not out\n");
continue;
+ }
}
}
- if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic))
+ if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) {
+ verbose(8, "-- type mismatch\n");
continue;
+ }
if ((a->ac_mflag & IPMAC_EVERY) != 0) {
gettimeofday(&tv, NULL);
@@ -492,8 +485,10 @@ int opts, lvl;
if (tv.tv_usec <= a->ac_lastusec)
t1--;
if (a->ac_second != 0) {
- if (t1 < a->ac_second)
+ if (t1 < a->ac_second) {
+ verbose(8, "-- too soon\n");
continue;
+ }
a->ac_lastsec = tv.tv_sec;
a->ac_lastusec = tv.tv_usec;
}
@@ -503,159 +498,149 @@ int opts, lvl;
a->ac_pktcnt++;
else if (a->ac_pktcnt == a->ac_packet) {
a->ac_pktcnt = 0;
+ verbose(8, "-- packet count\n");
continue;
} else {
a->ac_pktcnt++;
+ verbose(8, "-- packet count\n");
continue;
}
}
}
if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
- if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip)
+ if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) {
+ verbose(8, "-- dstip wrong\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
- if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
+ if (ip->ip_p != IPPROTO_UDP &&
+ ip->ip_p != IPPROTO_TCP) {
+ verbose(8, "-- not port protocol\n");
continue;
- if (tcp->th_dport != a->ac_dport)
+ }
+ if (tcp->th_dport != a->ac_dport) {
+ verbose(8, "-- dport mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_GROUP) != 0) {
if (strncmp(a->ac_group, ipf->fl_group,
- FR_GROUPLEN) != 0)
+ FR_GROUPLEN) != 0) {
+ verbose(8, "-- group mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
- if (strcmp(a->ac_iface, ipf->fl_ifname))
+ if (strcmp(a->ac_iface, ipf->fl_ifname)) {
+ verbose(8, "-- ifname mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
- if (a->ac_proto != ip->ip_p)
+ if (a->ac_proto != ip->ip_p) {
+ verbose(8, "-- protocol mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_RESULT) != 0) {
if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) {
- if (a->ac_result != IPMR_NOMATCH)
+ if (a->ac_result != IPMR_NOMATCH) {
+ verbose(8, "-- ff-flags mismatch\n");
continue;
+ }
} else if (FR_ISPASS(ipf->fl_flags)) {
- if (a->ac_result != IPMR_PASS)
+ if (a->ac_result != IPMR_PASS) {
+ verbose(8, "-- pass mismatch\n");
continue;
+ }
} else if (FR_ISBLOCK(ipf->fl_flags)) {
- if (a->ac_result != IPMR_BLOCK)
+ if (a->ac_result != IPMR_BLOCK) {
+ verbose(8, "-- block mismatch\n");
continue;
+ }
} else { /* Log only */
- if (a->ac_result != IPMR_LOG)
+ if (a->ac_result != IPMR_LOG) {
+ verbose(8, "-- log mismatch\n");
continue;
+ }
}
}
if ((a->ac_mflag & IPMAC_RULE) != 0) {
- if (a->ac_rule != ipf->fl_rule)
+ if (a->ac_rule != ipf->fl_rule) {
+ verbose(8, "-- rule mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
- if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip)
+ if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) {
+ verbose(8, "-- srcip mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
- if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP)
+ if (ip->ip_p != IPPROTO_UDP &&
+ ip->ip_p != IPPROTO_TCP) {
+ verbose(8, "-- port protocol mismatch\n");
continue;
- if (tcp->th_sport != a->ac_sport)
+ }
+ if (tcp->th_sport != a->ac_sport) {
+ verbose(8, "-- sport mismatch\n");
continue;
+ }
}
if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
- if (a->ac_logtag != ipf->fl_logtag)
+ if (a->ac_logtag != ipf->fl_logtag) {
+ verbose(8, "-- logtag %d != %d\n",
+ a->ac_logtag, ipf->fl_logtag);
continue;
+ }
}
if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag,
- IPFTAG_LEN) != 0)
+ IPFTAG_LEN) != 0) {
+ verbose(8, "-- nattag mismatch\n");
continue;
+ }
}
matched = 1;
+ verbose(8, "++ matched\n");
/*
- * It matched so now execute the command
+ * It matched so now perform the saves
*/
- if (a->ac_syslog != 0) {
- syslog(lvl, "%s", log);
- }
-
- if (a->ac_savefp != NULL) {
- if (a->ac_dflag & IPMDO_SAVERAW)
- fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp);
- else
- fputs(log, a->ac_savefp);
- }
-
- if (a->ac_exec != NULL) {
- switch (fork())
- {
- case 0 :
- {
- FILE *pi;
-
- pi = popen(a->ac_run, "w");
- if (pi != NULL) {
- fprintf(pi, "%s\n", log);
- if ((opts & OPT_HEXHDR) != 0) {
- dumphex(pi, 0, buf,
- sizeof(*ipl) +
- sizeof(*ipf));
- }
- if ((opts & OPT_HEXBODY) != 0) {
- dumphex(pi, 0, (char *)ip,
- ipf->fl_hlen +
- ipf->fl_plen);
- }
- pclose(pi);
- }
- exit(1);
- }
- case -1 :
- break;
- default :
- break;
- }
- }
+ for (d = a->ac_doing; d != NULL; d = d->ipmd_next)
+ (*d->ipmd_store)(d->ipmd_token, &msg);
}
return matched;
}
-static void free_action(a)
-ipmon_action_t *a;
+static void
+free_action(a)
+ ipmon_action_t *a;
{
- if (a->ac_savefile != NULL) {
- free(a->ac_savefile);
- a->ac_savefile = NULL;
- }
- if (a->ac_savefp != NULL) {
- fclose(a->ac_savefp);
- a->ac_savefp = NULL;
- }
- if (a->ac_exec != NULL) {
- free(a->ac_exec);
- if (a->ac_run == a->ac_exec)
- a->ac_run = NULL;
- a->ac_exec = NULL;
- }
- if (a->ac_run != NULL) {
- free(a->ac_run);
- a->ac_run = NULL;
+ ipmon_doing_t *d;
+
+ while ((d = a->ac_doing) != NULL) {
+ a->ac_doing = d->ipmd_next;
+ (*d->ipmd_saver->ims_destroy)(d->ipmd_token);
+ free(d);
}
+
if (a->ac_iface != NULL) {
free(a->ac_iface);
a->ac_iface = NULL;
@@ -665,24 +650,21 @@ ipmon_action_t *a;
}
-int load_config(file)
-char *file;
+int
+load_config(file)
+ char *file;
{
- ipmon_action_t *a;
FILE *fp;
char *s;
+ unload_config();
+
s = getenv("YYDEBUG");
if (s != NULL)
yydebug = atoi(s);
else
yydebug = 0;
- while ((a = alist) != NULL) {
- alist = a->ac_next;
- free_action(a);
- }
-
yylineNum = 1;
(void) yysettab(yywords);
@@ -698,3 +680,373 @@ char *file;
fclose(fp);
return 0;
}
+
+
+void
+unload_config()
+{
+ ipmon_saver_int_t *sav, **imsip;
+ ipmon_saver_t *is;
+ ipmon_action_t *a;
+
+ while ((a = alist) != NULL) {
+ alist = a->ac_next;
+ free_action(a);
+ }
+
+ /*
+ * Look for savers that have been added in dynamically from the
+ * configuration file.
+ */
+ for (imsip = &saverlist; (sav = *imsip) != NULL; ) {
+ if (sav->imsi_handle == NULL)
+ imsip = &sav->imsi_next;
+ else {
+ dlclose(sav->imsi_handle);
+
+ *imsip = sav->imsi_next;
+ is = sav->imsi_stor;
+ free(sav);
+
+ free(is->ims_name);
+ free(is);
+ }
+ }
+}
+
+
+void
+dump_config()
+{
+ ipmon_action_t *a;
+
+ for (a = alist; a != NULL; a = a->ac_next) {
+ print_action(a);
+
+ printf("#\n");
+ }
+}
+
+
+static void
+print_action(a)
+ ipmon_action_t *a;
+{
+ ipmon_doing_t *d;
+
+ printf("match { ");
+ print_match(a);
+ printf("; }\n");
+ printf("do {");
+ for (d = a->ac_doing; d != NULL; d = d->ipmd_next) {
+ printf("%s", d->ipmd_saver->ims_name);
+ if (d->ipmd_saver->ims_print != NULL) {
+ printf("(\"");
+ (*d->ipmd_saver->ims_print)(d->ipmd_token);
+ printf("\")");
+ }
+ printf(";");
+ }
+ printf("};\n");
+}
+
+
+void *
+add_doing(saver)
+ ipmon_saver_t *saver;
+{
+ ipmon_saver_int_t *it;
+
+ if (find_doing(saver->ims_name) == IPM_DOING)
+ return NULL;
+
+ it = calloc(1, sizeof(*it));
+ if (it == NULL)
+ return NULL;
+ it->imsi_stor = saver;
+ it->imsi_next = saverlist;
+ saverlist = it;
+ return it;
+}
+
+
+static int
+find_doing(string)
+ char *string;
+{
+ ipmon_saver_int_t *it;
+
+ for (it = saverlist; it != NULL; it = it->imsi_next) {
+ if (!strcmp(it->imsi_stor->ims_name, string))
+ return IPM_DOING;
+ }
+ return 0;
+}
+
+
+static ipmon_doing_t *
+build_doing(target, options)
+ char *target;
+ char *options;
+{
+ ipmon_saver_int_t *it;
+ char *strarray[2];
+ ipmon_doing_t *d, *d1;
+ ipmon_action_t *a;
+ ipmon_saver_t *save;
+
+ d = calloc(1, sizeof(*d));
+ if (d == NULL)
+ return NULL;
+
+ for (it = saverlist; it != NULL; it = it->imsi_next) {
+ if (!strcmp(it->imsi_stor->ims_name, target))
+ break;
+ }
+ if (it == NULL) {
+ free(d);
+ return NULL;
+ }
+
+ strarray[0] = options;
+ strarray[1] = NULL;
+
+ d->ipmd_token = (*it->imsi_stor->ims_parse)(strarray);
+ if (d->ipmd_token == NULL) {
+ free(d);
+ return NULL;
+ }
+
+ save = it->imsi_stor;
+ d->ipmd_saver = save;
+ d->ipmd_store = it->imsi_stor->ims_store;
+
+ /*
+ * Look for duplicate do-things that need to be dup'd
+ */
+ for (a = alist; a != NULL; a = a->ac_next) {
+ for (d1 = a->ac_doing; d1 != NULL; d1 = d1->ipmd_next) {
+ if (save != d1->ipmd_saver)
+ continue;
+ if (save->ims_match == NULL || save->ims_dup == NULL)
+ continue;
+ if ((*save->ims_match)(d->ipmd_token, d1->ipmd_token))
+ continue;
+
+ (*d->ipmd_saver->ims_destroy)(d->ipmd_token);
+ d->ipmd_token = (*save->ims_dup)(d1->ipmd_token);
+ break;
+ }
+ }
+
+ return d;
+}
+
+
+static void
+print_match(a)
+ ipmon_action_t *a;
+{
+ char *coma = "";
+
+ if ((a->ac_mflag & IPMAC_DIRECTION) != 0) {
+ printf("direction = ");
+ if (a->ac_direction == IPM_IN)
+ printf("in");
+ else if (a->ac_direction == IPM_OUT)
+ printf("out");
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_DSTIP) != 0) {
+ printf("%sdstip = ", coma);
+ printhostmask(AF_INET, &a->ac_dip, &a->ac_dmsk);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_DSTPORT) != 0) {
+ printf("%sdstport = %hu", coma, ntohs(a->ac_dport));
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_GROUP) != 0) {
+ char group[FR_GROUPLEN+1];
+
+ strncpy(group, a->ac_group, FR_GROUPLEN);
+ group[FR_GROUPLEN] = '\0';
+ printf("%sgroup = %s", coma, group);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_INTERFACE) != 0) {
+ printf("%siface = %s", coma, a->ac_iface);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_LOGTAG) != 0) {
+ printf("%slogtag = %u", coma, a->ac_logtag);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_NATTAG) != 0) {
+ char tag[17];
+
+ strncpy(tag, a->ac_nattag, 16);
+ tag[16] = '\0';
+ printf("%snattag = %s", coma, tag);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) {
+ printf("%sprotocol = %u", coma, a->ac_proto);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_RESULT) != 0) {
+ printf("%sresult = ", coma);
+ switch (a->ac_result)
+ {
+ case IPMR_LOG :
+ printf("log");
+ break;
+ case IPMR_PASS :
+ printf("pass");
+ break;
+ case IPMR_BLOCK :
+ printf("block");
+ break;
+ case IPMR_NOMATCH :
+ printf("nomatch");
+ break;
+ }
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_RULE) != 0) {
+ printf("%srule = %u", coma, a->ac_rule);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_EVERY) != 0) {
+ if (a->ac_packet > 1) {
+ printf("%severy %d packets", coma, a->ac_packet);
+ coma = ", ";
+ } else if (a->ac_packet == 1) {
+ printf("%severy packet", coma);
+ coma = ", ";
+ }
+ if (a->ac_second > 1) {
+ printf("%severy %d seconds", coma, a->ac_second);
+ coma = ", ";
+ } else if (a->ac_second == 1) {
+ printf("%severy second", coma);
+ coma = ", ";
+ }
+ }
+
+ if ((a->ac_mflag & IPMAC_SRCIP) != 0) {
+ printf("%ssrcip = ", coma);
+ printhostmask(AF_INET, &a->ac_sip, &a->ac_smsk);
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_SRCPORT) != 0) {
+ printf("%ssrcport = %hu", coma, ntohs(a->ac_sport));
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_TYPE) != 0) {
+ printf("%stype = ", coma);
+ switch (a->ac_type)
+ {
+ case IPL_LOGIPF :
+ printf("ipf");
+ break;
+ case IPL_LOGSTATE :
+ printf("state");
+ break;
+ case IPL_LOGNAT :
+ printf("nat");
+ break;
+ }
+ coma = ", ";
+ }
+
+ if ((a->ac_mflag & IPMAC_WITH) != 0) {
+ printf("%swith ", coma);
+ coma = ", ";
+ }
+}
+
+
+static int
+install_saver(name, path)
+ char *name, *path;
+{
+ ipmon_saver_int_t *isi;
+ ipmon_saver_t *is;
+ char nbuf[80];
+
+ if (find_doing(name) == IPM_DOING)
+ return -1;
+
+ isi = calloc(1, sizeof(*isi));
+ if (isi == NULL)
+ return -1;
+
+ is = calloc(1, sizeof(*is));
+ if (is == NULL)
+ goto loaderror;
+
+ is->ims_name = name;
+
+#ifdef RTLD_LAZY
+ isi->imsi_handle = dlopen(path, RTLD_LAZY);
+#endif
+#ifdef DL_LAZY
+ isi->imsi_handle = dlopen(path, DL_LAZY);
+#endif
+
+ if (isi->imsi_handle == NULL)
+ goto loaderror;
+
+ snprintf(nbuf, sizeof(nbuf), "%sdup", name);
+ is->ims_dup = (ims_dup_func_t)dlsym(isi->imsi_handle, nbuf);
+
+ snprintf(nbuf, sizeof(nbuf), "%sdestroy", name);
+ is->ims_destroy = (ims_destroy_func_t)dlsym(isi->imsi_handle, nbuf);
+ if (is->ims_destroy == NULL)
+ goto loaderror;
+
+ snprintf(nbuf, sizeof(nbuf), "%smatch", name);
+ is->ims_match = (ims_match_func_t)dlsym(isi->imsi_handle, nbuf);
+
+ snprintf(nbuf, sizeof(nbuf), "%sparse", name);
+ is->ims_parse = (ims_parse_func_t)dlsym(isi->imsi_handle, nbuf);
+ if (is->ims_parse == NULL)
+ goto loaderror;
+
+ snprintf(nbuf, sizeof(nbuf), "%sprint", name);
+ is->ims_print = (ims_print_func_t)dlsym(isi->imsi_handle, nbuf);
+ if (is->ims_print == NULL)
+ goto loaderror;
+
+ snprintf(nbuf, sizeof(nbuf), "%sstore", name);
+ is->ims_store = (ims_store_func_t)dlsym(isi->imsi_handle, nbuf);
+ if (is->ims_store == NULL)
+ goto loaderror;
+
+ isi->imsi_stor = is;
+ isi->imsi_next = saverlist;
+ saverlist = isi;
+
+ return 0;
+
+loaderror:
+ if (isi->imsi_handle != NULL)
+ dlclose(isi->imsi_handle);
+ free(isi);
+ if (is != NULL)
+ free(is);
+ return -1;
+}
diff --git a/contrib/ipfilter/tools/ipnat.c b/contrib/ipfilter/tools/ipnat.c
index 28e29ec74199..448c1c0d2d2a 100644
--- a/contrib/ipfilter/tools/ipnat.c
+++ b/contrib/ipfilter/tools/ipnat.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
@@ -67,7 +67,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.24.2.11 2007/09/25 08:27:34 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
@@ -79,23 +79,25 @@ char thishost[MAXHOSTNAMELEN];
extern char *optarg;
-void dostats __P((int, natstat_t *, int, int));
-void dotable __P((natstat_t *, int, int));
-void flushtable __P((int, int));
+void dostats __P((int, natstat_t *, int, int, int *));
+void dotable __P((natstat_t *, int, int, int, char *));
+void flushtable __P((int, int, int *));
void usage __P((char *));
int main __P((int, char*[]));
void showhostmap __P((natstat_t *nsp));
void natstat_dead __P((natstat_t *, char *));
-void dostats_live __P((int, natstat_t *, int));
+void dostats_live __P((int, natstat_t *, int, int *));
void showhostmap_dead __P((natstat_t *));
void showhostmap_live __P((int, natstat_t *));
-void dostats_dead __P((natstat_t *, int));
-void showtqtable_live __P((int));
+void dostats_dead __P((natstat_t *, int, int *));
+int nat_matcharray __P((nat_t *, int *));
-int opts;
+int opts;
+int nohdrfields = 0;
+wordtab_t *nat_fields = NULL;
void usage(name)
-char *name;
+ char *name;
{
fprintf(stderr, "Usage: %s [-CFhlnrRsv] [-f filename]\n", name);
exit(1);
@@ -103,12 +105,12 @@ char *name;
int main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
+ int fd, c, mode, *natfilter;
char *file, *core, *kernel;
natstat_t ns, *nsp;
- int fd, c, mode;
ipfobj_t obj;
fd = -1;
@@ -118,8 +120,11 @@ char *argv[];
core = NULL;
kernel = NULL;
mode = O_RDWR;
+ natfilter = NULL;
- while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1)
+ assigndefined(getenv("IPNAT_PREDEFINED"));
+
+ while ((c = getopt(argc, argv, "CdFf:hlm:M:N:nO:prRsv")) != -1)
switch (c)
{
case 'C' :
@@ -141,6 +146,9 @@ char *argv[];
opts |= OPT_LIST;
mode = O_RDONLY;
break;
+ case 'm' :
+ natfilter = parseipfexpr(optarg, NULL);
+ break;
case 'M' :
core = optarg;
break;
@@ -148,9 +156,15 @@ char *argv[];
kernel = optarg;
break;
case 'n' :
- opts |= OPT_DONOTHING;
+ opts |= OPT_DONOTHING|OPT_DONTOPEN;
mode = O_RDONLY;
break;
+ case 'O' :
+ nat_fields = parsefields(natfields, optarg);
+ break;
+ case 'p' :
+ opts |= OPT_PURGE;
+ break;
case 'R' :
opts |= OPT_NORESOLVE;
break;
@@ -168,6 +182,12 @@ char *argv[];
usage(argv[0]);
}
+ if (((opts & OPT_PURGE) != 0) && ((opts & OPT_REMOVE) == 0)) {
+ (void) fprintf(stderr, "%s: -p must be used with -r\n",
+ argv[0]);
+ exit(1);
+ }
+
initparse();
if ((kernel != NULL) || (core != NULL)) {
@@ -200,7 +220,7 @@ char *argv[];
obj.ipfo_size = sizeof(*nsp);
obj.ipfo_ptr = (void *)nsp;
if (ioctl(fd, SIOCGNATS, &obj) == -1) {
- perror("ioctl(SIOCGNATS)");
+ ipferror(fd, "ioctl(SIOCGNATS)");
exit(1);
}
(void) setgid(getgid());
@@ -211,17 +231,17 @@ char *argv[];
natstat_dead(nsp, kernel);
if (opts & (OPT_LIST|OPT_STAT))
- dostats(fd, nsp, opts, 0);
+ dostats(fd, nsp, opts, 0, natfilter);
exit(0);
}
if (opts & (OPT_FLUSH|OPT_CLEAR))
- flushtable(fd, opts);
+ flushtable(fd, opts, natfilter);
if (file) {
- ipnat_parsefile(fd, ipnat_addrule, ioctl, file);
+ return ipnat_parsefile(fd, ipnat_addrule, ioctl, file);
}
if (opts & (OPT_LIST|OPT_STAT))
- dostats(fd, nsp, opts, 1);
+ dostats(fd, nsp, opts, 1, natfilter);
return 0;
}
@@ -231,8 +251,8 @@ char *argv[];
* rather than doing ioctl's.
*/
void natstat_dead(nsp, kernel)
-natstat_t *nsp;
-char *kernel;
+ natstat_t *nsp;
+ char *kernel;
{
struct nlist nat_nlist[10] = {
{ "nat_table" }, /* 0 */
@@ -243,7 +263,6 @@ char *kernel;
{ "ipf_rdrrules_sz" }, /* 5 */
{ "ipf_hostmap_sz" },
{ "nat_instances" },
- { "ap_sess_list" },
{ NULL }
};
void *tables[2];
@@ -259,8 +278,8 @@ char *kernel;
* one in individually.
*/
kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
- nsp->ns_table[0] = tables[0];
- nsp->ns_table[1] = tables[1];
+ nsp->ns_side[0].ns_table = tables[0];
+ nsp->ns_side[1].ns_table = tables[1];
kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value,
sizeof(nsp->ns_list));
@@ -276,8 +295,6 @@ char *kernel;
sizeof(nsp->ns_hostmap_sz));
kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value,
sizeof(nsp->ns_instances));
- kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
- sizeof(nsp->ns_apslist));
}
@@ -285,23 +302,40 @@ char *kernel;
* Issue an ioctl to flush either the NAT rules table or the active mapping
* table or both.
*/
-void flushtable(fd, opts)
-int fd, opts;
+void flushtable(fd, opts, match)
+ int fd, opts, *match;
{
int n = 0;
if (opts & OPT_FLUSH) {
n = 0;
- if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1)
- perror("ioctl(SIOCFLNAT)");
- else
+ if (!(opts & OPT_DONOTHING)) {
+ if (match != NULL) {
+ ipfobj_t obj;
+
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_size = match[0] * sizeof(int);
+ obj.ipfo_type = IPFOBJ_IPFEXPR;
+ obj.ipfo_ptr = match;
+ if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) {
+ ipferror(fd, "ioctl(SIOCMATCHFLUSH)");
+ n = -1;
+ } else {
+ n = obj.ipfo_retval;
+ }
+ } else if (ioctl(fd, SIOCIPFFL, &n) == -1) {
+ ipferror(fd, "ioctl(SIOCIPFFL)");
+ n = -1;
+ }
+ }
+ if (n >= 0)
printf("%d entries flushed from NAT table\n", n);
}
if (opts & OPT_CLEAR) {
n = 1;
if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1)
- perror("ioctl(SIOCCNATL)");
+ ipferror(fd, "ioctl(SIOCCNATL)");
else
printf("%d entries flushed from NAT list\n", n);
}
@@ -311,34 +345,65 @@ int fd, opts;
/*
* Display NAT statistics.
*/
-void dostats_dead(nsp, opts)
-natstat_t *nsp;
-int opts;
+void dostats_dead(nsp, opts, filter)
+ natstat_t *nsp;
+ int opts, *filter;
{
nat_t *np, nat;
ipnat_t ipn;
+ int i;
- printf("List of active MAP/Redirect filters:\n");
- while (nsp->ns_list) {
- if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
- sizeof(ipn))) {
- perror("kmemcpy");
- break;
+ if (nat_fields == NULL) {
+ printf("List of active MAP/Redirect filters:\n");
+ while (nsp->ns_list) {
+ if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
+ sizeof(ipn))) {
+ perror("kmemcpy");
+ break;
+ }
+ if (opts & OPT_HITS)
+ printf("%lu ", ipn.in_hits);
+ printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
+ nsp->ns_list = ipn.in_next;
}
- if (opts & OPT_HITS)
- printf("%lu ", ipn.in_hits);
- printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
- nsp->ns_list = ipn.in_next;
}
- printf("\nList of active sessions:\n");
+ if (nat_fields == NULL) {
+ printf("\nList of active sessions:\n");
+
+ } else if (nohdrfields == 0) {
+ for (i = 0; nat_fields[i].w_value != 0; i++) {
+ printfieldhdr(natfields, nat_fields + i);
+ if (nat_fields[i + 1].w_value != 0)
+ printf("\t");
+ }
+ printf("\n");
+ }
for (np = nsp->ns_instances; np; np = nat.nat_next) {
if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
break;
- printactivenat(&nat, opts, 0, nsp->ns_ticks);
- if (nat.nat_aps)
- printaps(nat.nat_aps, opts);
+ if ((filter != NULL) && (nat_matcharray(&nat, filter) == 0))
+ continue;
+ if (nat_fields != NULL) {
+ for (i = 0; nat_fields[i].w_value != 0; i++) {
+ printnatfield(&nat, nat_fields[i].w_value);
+ if (nat_fields[i + 1].w_value != 0)
+ printf("\t");
+ }
+ printf("\n");
+ } else {
+ printactivenat(&nat, opts, nsp->ns_ticks);
+ if (nat.nat_aps) {
+ int proto;
+
+ if (nat.nat_dir & NAT_OUTBOUND)
+ proto = nat.nat_pr[1];
+ else
+ proto = nat.nat_pr[0];
+ printaps(nat.nat_aps, opts, proto);
+ }
+ }
}
if (opts & OPT_VERBOSE)
@@ -346,62 +411,39 @@ int opts;
}
-void dostats(fd, nsp, opts, alive)
-natstat_t *nsp;
-int fd, opts, alive;
-{
- /*
- * Show statistics ?
- */
- if (opts & OPT_STAT) {
- printf("mapped\tin\t%lu\tout\t%lu\n",
- nsp->ns_mapped[0], nsp->ns_mapped[1]);
- printf("added\t%lu\texpired\t%lu\n",
- nsp->ns_added, nsp->ns_expire);
- printf("no memory\t%lu\tbad nat\t%lu\n",
- nsp->ns_memfail, nsp->ns_badnat);
- printf("inuse\t%lu\norphans\t%u\nrules\t%lu\n",
- nsp->ns_inuse, nsp->ns_orphans, nsp->ns_rules);
- printf("wilds\t%u\n", nsp->ns_wilds);
- dotable(nsp, fd, alive);
- if (opts & OPT_VERBOSE)
- printf("table %p list %p\n",
- nsp->ns_table, nsp->ns_list);
- if (alive)
- showtqtable_live(fd);
- }
-
- if (opts & OPT_LIST) {
- if (alive)
- dostats_live(fd, nsp, opts);
- else
- dostats_dead(nsp, opts);
- }
-}
-
-
-void dotable(nsp, fd, alive)
-natstat_t *nsp;
-int fd, alive;
+void dotable(nsp, fd, alive, which, side)
+ natstat_t *nsp;
+ int fd, alive, which;
+ char *side;
{
- int sz, i, used, totallen, maxlen, minlen;
+ int sz, i, used, maxlen, minlen, totallen;
ipftable_t table;
- u_long *buckets;
+ u_int *buckets;
ipfobj_t obj;
sz = sizeof(*buckets) * nsp->ns_nattab_sz;
- buckets = (u_long *)malloc(sz);
+ buckets = (u_int *)malloc(sz);
+ if (buckets == NULL) {
+ fprintf(stderr,
+ "cannot allocate memory (%d) for buckets\n", sz);
+ return;
+ }
obj.ipfo_rev = IPFILTER_VERSION;
obj.ipfo_type = IPFOBJ_GTABLE;
obj.ipfo_size = sizeof(table);
obj.ipfo_ptr = &table;
- table.ita_type = IPFTABLE_BUCKETS_NATIN;
+ if (which == 0) {
+ table.ita_type = IPFTABLE_BUCKETS_NATIN;
+ } else if (which == 1) {
+ table.ita_type = IPFTABLE_BUCKETS_NATOUT;
+ }
table.ita_table = buckets;
if (alive) {
if (ioctl(fd, SIOCGTABL, &obj) != 0) {
+ ipferror(fd, "SIOCFTABL");
free(buckets);
return;
}
@@ -412,9 +454,9 @@ int fd, alive;
}
}
+ minlen = nsp->ns_side[which].ns_inuse;
totallen = 0;
maxlen = 0;
- minlen = nsp->ns_inuse;
used = 0;
for (i = 0; i < nsp->ns_nattab_sz; i++) {
@@ -427,27 +469,84 @@ int fd, alive;
totallen += buckets[i];
}
- printf("hash efficiency\t%2.2f%%\n",
- totallen ? ((float)used / totallen) * 100.0 : 0.0);
- printf("bucket usage\t%2.2f%%\n",
- ((float)used / nsp->ns_nattab_sz) * 100.0);
- printf("minimal length\t%d\n", minlen);
- printf("maximal length\t%d\n", maxlen);
- printf("average length\t%.3f\n", used ? (float)totallen / used : 0.0);
+ printf("%d%%\thash efficiency %s\n",
+ totallen ? used * 100 / totallen : 0, side);
+ printf("%2.2f%%\tbucket usage %s\n",
+ ((float)used / nsp->ns_nattab_sz) * 100.0, side);
+ printf("%d\tminimal length %s\n", minlen, side);
+ printf("%d\tmaximal length %s\n", maxlen, side);
+ printf("%.3f\taverage length %s\n",
+ used ? ((float)totallen / used) : 0.0, side);
+
+ free(buckets);
+}
+
+
+void dostats(fd, nsp, opts, alive, filter)
+ natstat_t *nsp;
+ int fd, opts, alive, *filter;
+{
+ /*
+ * Show statistics ?
+ */
+ if (opts & OPT_STAT) {
+ printnatside("in", &nsp->ns_side[0]);
+ dotable(nsp, fd, alive, 0, "in");
+
+ printnatside("out", &nsp->ns_side[1]);
+ dotable(nsp, fd, alive, 1, "out");
+
+ printf("%lu\tlog successes\n", nsp->ns_side[0].ns_log);
+ printf("%lu\tlog failures\n", nsp->ns_side[1].ns_log);
+ printf("%lu\tadded in\n%lu\tadded out\n",
+ nsp->ns_side[0].ns_added,
+ nsp->ns_side[1].ns_added);
+ printf("%u\tactive\n", nsp->ns_active);
+ printf("%lu\ttransparent adds\n", nsp->ns_addtrpnt);
+ printf("%lu\tdivert build\n", nsp->ns_divert_build);
+ printf("%lu\texpired\n", nsp->ns_expire);
+ printf("%lu\tflush all\n", nsp->ns_flush_all);
+ printf("%lu\tflush closing\n", nsp->ns_flush_closing);
+ printf("%lu\tflush queue\n", nsp->ns_flush_queue);
+ printf("%lu\tflush state\n", nsp->ns_flush_state);
+ printf("%lu\tflush timeout\n", nsp->ns_flush_timeout);
+ printf("%lu\thostmap new\n", nsp->ns_hm_new);
+ printf("%lu\thostmap fails\n", nsp->ns_hm_newfail);
+ printf("%lu\thostmap add\n", nsp->ns_hm_addref);
+ printf("%lu\thostmap NULL rule\n", nsp->ns_hm_nullnp);
+ printf("%lu\tlog ok\n", nsp->ns_log_ok);
+ printf("%lu\tlog fail\n", nsp->ns_log_fail);
+ printf("%u\torphan count\n", nsp->ns_orphans);
+ printf("%u\trule count\n", nsp->ns_rules);
+ printf("%u\tmap rules\n", nsp->ns_rules_map);
+ printf("%u\trdr rules\n", nsp->ns_rules_rdr);
+ printf("%u\twilds\n", nsp->ns_wilds);
+ if (opts & OPT_VERBOSE)
+ printf("list %p\n", nsp->ns_list);
+ }
+
+ if (opts & OPT_LIST) {
+ if (alive)
+ dostats_live(fd, nsp, opts, filter);
+ else
+ dostats_dead(nsp, opts, filter);
+ }
}
/*
* Display NAT statistics.
*/
-void dostats_live(fd, nsp, opts)
-natstat_t *nsp;
-int fd, opts;
+void dostats_live(fd, nsp, opts, filter)
+ natstat_t *nsp;
+ int fd, opts, *filter;
{
ipfgeniter_t iter;
+ char buffer[2000];
ipfobj_t obj;
- ipnat_t ipn;
+ ipnat_t *ipn;
nat_t nat;
+ int i;
bzero((char *)&obj, sizeof(obj));
obj.ipfo_rev = IPFILTER_VERSION;
@@ -457,22 +556,39 @@ int fd, opts;
iter.igi_type = IPFGENITER_IPNAT;
iter.igi_nitems = 1;
- iter.igi_data = &ipn;
+ iter.igi_data = buffer;
+ ipn = (ipnat_t *)buffer;
/*
* Show list of NAT rules and NAT sessions ?
*/
- printf("List of active MAP/Redirect filters:\n");
- while (nsp->ns_list) {
- if (ioctl(fd, SIOCGENITER, &obj) == -1)
- break;
- if (opts & OPT_HITS)
- printf("%lu ", ipn.in_hits);
- printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
- nsp->ns_list = ipn.in_next;
+ if (nat_fields == NULL) {
+ printf("List of active MAP/Redirect filters:\n");
+ while (nsp->ns_list) {
+ if (ioctl(fd, SIOCGENITER, &obj) == -1)
+ break;
+ if (opts & OPT_HITS)
+ printf("%lu ", ipn->in_hits);
+ printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
+ nsp->ns_list = ipn->in_next;
+ }
+ }
+
+ if (nat_fields == NULL) {
+ printf("\nList of active sessions:\n");
+
+ } else if (nohdrfields == 0) {
+ for (i = 0; nat_fields[i].w_value != 0; i++) {
+ printfieldhdr(natfields, nat_fields + i);
+ if (nat_fields[i + 1].w_value != 0)
+ printf("\t");
+ }
+ printf("\n");
}
- printf("\nList of active sessions:\n");
+ i = IPFGENITER_IPNAT;
+ (void) ioctl(fd,SIOCIPFDELTOK, &i);
+
iter.igi_type = IPFGENITER_NAT;
iter.igi_nitems = 1;
@@ -481,14 +597,35 @@ int fd, opts;
while (nsp->ns_instances != NULL) {
if (ioctl(fd, SIOCGENITER, &obj) == -1)
break;
- printactivenat(&nat, opts, 1, nsp->ns_ticks);
- if (nat.nat_aps)
- printaps(nat.nat_aps, opts);
+ if ((filter != NULL) && (nat_matcharray(&nat, filter) == 0))
+ continue;
+ if (nat_fields != NULL) {
+ for (i = 0; nat_fields[i].w_value != 0; i++) {
+ printnatfield(&nat, nat_fields[i].w_value);
+ if (nat_fields[i + 1].w_value != 0)
+ printf("\t");
+ }
+ printf("\n");
+ } else {
+ printactivenat(&nat, opts, nsp->ns_ticks);
+ if (nat.nat_aps) {
+ int proto;
+
+ if (nat.nat_dir & NAT_OUTBOUND)
+ proto = nat.nat_pr[1];
+ else
+ proto = nat.nat_pr[0];
+ printaps(nat.nat_aps, opts, proto);
+ }
+ }
nsp->ns_instances = nat.nat_next;
}
if (opts & OPT_VERBOSE)
showhostmap_live(fd, nsp);
+
+ i = IPFGENITER_NAT;
+ (void) ioctl(fd,SIOCIPFDELTOK, &i);
}
@@ -496,7 +633,7 @@ int fd, opts;
* Display the active host mapping table.
*/
void showhostmap_dead(nsp)
-natstat_t *nsp;
+ natstat_t *nsp;
{
hostmap_t hm, *hmp, **maptable;
u_int hv;
@@ -532,12 +669,13 @@ natstat_t *nsp;
* Display the active host mapping table.
*/
void showhostmap_live(fd, nsp)
-int fd;
-natstat_t *nsp;
+ int fd;
+ natstat_t *nsp;
{
ipfgeniter_t iter;
hostmap_t hm;
ipfobj_t obj;
+ int i;
bzero((char *)&obj, sizeof(obj));
obj.ipfo_rev = IPFILTER_VERSION;
@@ -554,25 +692,167 @@ natstat_t *nsp;
while (nsp->ns_maplist != NULL) {
if (ioctl(fd, SIOCGENITER, &obj) == -1)
break;
- printhostmap(&hm, 0);
+ printhostmap(&hm, hm.hm_hv);
nsp->ns_maplist = hm.hm_next;
}
+
+ i = IPFGENITER_HOSTMAP;
+ (void) ioctl(fd,SIOCIPFDELTOK, &i);
}
-void showtqtable_live(fd)
-int fd;
+int nat_matcharray(nat, array)
+ nat_t *nat;
+ int *array;
{
- ipftq_t table[IPF_TCP_NSTATES];
- ipfobj_t obj;
+ int i, n, *x, rv, p;
+ ipfexp_t *e;
- bzero((char *)&obj, sizeof(obj));
- obj.ipfo_rev = IPFILTER_VERSION;
- obj.ipfo_size = sizeof(table);
- obj.ipfo_ptr = (void *)table;
- obj.ipfo_type = IPFOBJ_STATETQTAB;
+ rv = 0;
+ n = array[0];
+ x = array + 1;
+
+ for (; n > 0; x += 3 + x[3], rv = 0) {
+ e = (ipfexp_t *)x;
+ if (e->ipfe_cmd == IPF_EXP_END)
+ break;
+ n -= e->ipfe_size;
+
+ p = e->ipfe_cmd >> 16;
+ if ((p != 0) && (p != nat->nat_pr[1]))
+ break;
+
+ switch (e->ipfe_cmd)
+ {
+ case IPF_EXP_IP_PR :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (nat->nat_pr[1] == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_IP_SRCADDR :
+ if (nat->nat_v[0] != 4)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= ((nat->nat_osrcaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]) ||
+ ((nat->nat_nsrcaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]);
+ }
+ break;
- if (ioctl(fd, SIOCGTQTAB, &obj) == 0) {
- printtqtable(table);
+ case IPF_EXP_IP_DSTADDR :
+ if (nat->nat_v[0] != 4)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= ((nat->nat_odstaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]) ||
+ ((nat->nat_ndstaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]);
+ }
+ break;
+
+ case IPF_EXP_IP_ADDR :
+ if (nat->nat_v[0] != 4)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= ((nat->nat_osrcaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]) ||
+ ((nat->nat_nsrcaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]) ||
+ ((nat->nat_odstaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]) ||
+ ((nat->nat_ndstaddr &
+ e->ipfe_arg0[i * 2 + 1]) ==
+ e->ipfe_arg0[i * 2]);
+ }
+ break;
+
+#ifdef USE_INET6
+ case IPF_EXP_IP6_SRCADDR :
+ if (nat->nat_v[0] != 6)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= IP6_MASKEQ(&nat->nat_osrc6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]) ||
+ IP6_MASKEQ(&nat->nat_nsrc6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]);
+ }
+ break;
+
+ case IPF_EXP_IP6_DSTADDR :
+ if (nat->nat_v[0] != 6)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= IP6_MASKEQ(&nat->nat_odst6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]) ||
+ IP6_MASKEQ(&nat->nat_ndst6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]);
+ }
+ break;
+
+ case IPF_EXP_IP6_ADDR :
+ if (nat->nat_v[0] != 6)
+ break;
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= IP6_MASKEQ(&nat->nat_osrc6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]) ||
+ IP6_MASKEQ(&nat->nat_nsrc6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]) ||
+ IP6_MASKEQ(&nat->nat_odst6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]) ||
+ IP6_MASKEQ(&nat->nat_ndst6,
+ &e->ipfe_arg0[i * 8 + 4],
+ &e->ipfe_arg0[i * 8]);
+ }
+ break;
+#endif
+
+ case IPF_EXP_UDP_PORT :
+ case IPF_EXP_TCP_PORT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (nat->nat_osport == e->ipfe_arg0[i]) ||
+ (nat->nat_nsport == e->ipfe_arg0[i]) ||
+ (nat->nat_odport == e->ipfe_arg0[i]) ||
+ (nat->nat_ndport == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_UDP_SPORT :
+ case IPF_EXP_TCP_SPORT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (nat->nat_osport == e->ipfe_arg0[i]) ||
+ (nat->nat_nsport == e->ipfe_arg0[i]);
+ }
+ break;
+
+ case IPF_EXP_UDP_DPORT :
+ case IPF_EXP_TCP_DPORT :
+ for (i = 0; !rv && i < e->ipfe_narg; i++) {
+ rv |= (nat->nat_odport == e->ipfe_arg0[i]) ||
+ (nat->nat_ndport == e->ipfe_arg0[i]);
+ }
+ break;
+ }
+ rv ^= e->ipfe_not;
+
+ if (rv == 0)
+ break;
}
+
+ return rv;
}
diff --git a/contrib/ipfilter/tools/ipnat_y.y b/contrib/ipfilter/tools/ipnat_y.y
index 7109f60ec710..71fb8ee37106 100644
--- a/contrib/ipfilter/tools/ipnat_y.y
+++ b/contrib/ipfilter/tools/ipnat_y.y
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -60,33 +60,58 @@ static int natfd = -1;
static ioctlfunc_t natioctlfunc = NULL;
static addfunc_t nataddfunc = NULL;
static int suggest_port = 0;
+static proxyrule_t *prules = NULL;
+static int parser_error = 0;
static void newnatrule __P((void));
static void setnatproto __P((int));
-
+static void setmapifnames __P((void));
+static void setrdrifnames __P((void));
+static void proxy_setconfig __P((int));
+static void proxy_unsetconfig __P((void));
+static namelist_t *proxy_dns_add_pass __P((char *, char *));
+static namelist_t *proxy_dns_add_block __P((char *, char *));
+static void proxy_addconfig __P((char *, int, char *, namelist_t *));
+static void proxy_loadconfig __P((int, ioctlfunc_t, char *, int,
+ char *, namelist_t *));
+static void proxy_loadrules __P((int, ioctlfunc_t, proxyrule_t *));
+static void setmapifnames __P((void));
+static void setrdrifnames __P((void));
+static void setifname __P((ipnat_t **, int, char *));
+static int addname __P((ipnat_t **, char *));
%}
%union {
char *str;
u_32_t num;
- struct in_addr ipa;
+ struct {
+ i6addr_t a;
+ int f;
+ } ipa;
frentry_t fr;
frtuc_t *frt;
u_short port;
struct {
- u_short p1;
- u_short p2;
+ int p1;
+ int p2;
int pc;
} pc;
struct {
- struct in_addr a;
- struct in_addr m;
+ i6addr_t a;
+ i6addr_t m;
+ int t; /* Address type */
+ int u;
+ int f; /* Family */
+ int v; /* IP version */
+ int s; /* 0 = number, 1 = text */
+ int n; /* number */
} ipp;
union i6addr ip6;
+ namelist_t *names;
};
%token <num> YY_NUMBER YY_HEX
%token <str> YY_STR
-%token YY_COMMENT
+%token YY_COMMENT
%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
%token YY_RANGE_OUT YY_RANGE_IN
%token <ip6> YY_IPV6
@@ -95,23 +120,42 @@ static void setnatproto __P((int));
%token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY
%token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY
%token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG
-%token IPNY_TLATE IPNY_SEQUENTIAL
+%token IPNY_TLATE IPNY_POOL IPNY_HASH IPNY_NO IPNY_REWRITE IPNY_PROTO
+%token IPNY_ON IPNY_SRC IPNY_DST IPNY_IN IPNY_OUT IPNY_DIVERT
+%token IPNY_CONFIG IPNY_ALLOW IPNY_DENY IPNY_DNS IPNY_INET IPNY_INET6
+%token IPNY_SEQUENTIAL IPNY_DSTLIST IPNY_PURGE
%type <port> portspec
%type <num> hexnumber compare range proto
-%type <ipa> hostname ipv4
-%type <ipp> addr nummask rhaddr
-%type <pc> portstuff
+%type <num> saddr daddr sobject dobject mapfrom rdrfrom dip
+%type <ipa> hostname ipv4 ipaddr
+%type <ipp> addr rhsaddr rhdaddr erhdaddr
+%type <pc> portstuff portpair comaports srcports dstports
+%type <names> dnslines dnsline
%%
file: line
| assign
| file line
| file assign
+ | file pconf ';'
;
-line: xx rule { while ((nat = nattop) != NULL) {
+line: xx rule { int err;
+ while ((nat = nattop) != NULL) {
+ if (nat->in_v[0] == 0)
+ nat->in_v[0] = 4;
+ if (nat->in_v[1] == 0)
+ nat->in_v[1] = nat->in_v[0];
nattop = nat->in_next;
- (*nataddfunc)(natfd, natioctlfunc, nat);
+ err = (*nataddfunc)(natfd, natioctlfunc, nat);
free(nat);
+ if (err != 0) {
+ parser_error = err;
+ break;
+ }
+ }
+ if (parser_error == 0 && prules != NULL) {
+ proxy_loadrules(natfd, natioctlfunc, prules);
+ prules = NULL;
}
resetlexer();
}
@@ -136,206 +180,541 @@ xx: { newnatrule(); }
rule: map eol
| mapblock eol
| redir eol
+ | rewrite ';'
+ | divert ';'
+ ;
+
+no: IPNY_NO { nat->in_flags |= IPN_NO; }
;
eol: | ';'
;
-map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions
- { nat->in_v = 4;
- nat->in_inip = $3.a.s_addr;
- nat->in_inmsk = $3.m.s_addr;
- nat->in_outip = $5.a.s_addr;
- nat->in_outmsk = $5.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
- if ((nat->in_flags & IPN_TCPUDP) == 0)
- setnatproto(nat->in_p);
- if (((nat->in_redir & NAT_MAPBLK) != 0) ||
- ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
- nat_setgroupmap(nat);
+map: mapit ifnames addr tlate rhsaddr proxy mapoptions
+ { if ($3.f != 0 && $3.f != $5.f && $5.f != 0)
+ yyerror("3.address family mismatch");
+ if (nat->in_v[0] == 0 && $5.v != 0)
+ nat->in_v[0] = $5.v;
+ else if (nat->in_v[0] == 0 && $3.v != 0)
+ nat->in_v[0] = $3.v;
+ if (nat->in_v[1] == 0 && $5.v != 0)
+ nat->in_v[1] = $5.v;
+ else if (nat->in_v[1] == 0 && $3.v != 0)
+ nat->in_v[1] = $3.v;
+ nat->in_osrcatype = $3.t;
+ bcopy(&$3.a, &nat->in_osrc.na_addr[0],
+ sizeof($3.a));
+ bcopy(&$3.m, &nat->in_osrc.na_addr[1],
+ sizeof($3.a));
+ nat->in_nsrcatype = $5.t;
+ nat->in_nsrcafunc = $5.u;
+ bcopy(&$5.a, &nat->in_nsrc.na_addr[0],
+ sizeof($5.a));
+ bcopy(&$5.m, &nat->in_nsrc.na_addr[1],
+ sizeof($5.a));
+
+ setmapifnames();
+ }
+ | mapit ifnames addr tlate rhsaddr mapport mapoptions
+ { if ($3.f != $5.f && $3.f != 0 && $5.f != 0)
+ yyerror("4.address family mismatch");
+ if (nat->in_v[1] == 0 && $5.v != 0)
+ nat->in_v[1] = $5.v;
+ else if (nat->in_v[0] == 0 && $3.v != 0)
+ nat->in_v[0] = $3.v;
+ if (nat->in_v[0] == 0 && $5.v != 0)
+ nat->in_v[0] = $5.v;
+ else if (nat->in_v[1] == 0 && $3.v != 0)
+ nat->in_v[1] = $3.v;
+ nat->in_osrcatype = $3.t;
+ bcopy(&$3.a, &nat->in_osrc.na_addr[0],
+ sizeof($3.a));
+ bcopy(&$3.m, &nat->in_osrc.na_addr[1],
+ sizeof($3.a));
+ nat->in_nsrcatype = $5.t;
+ nat->in_nsrcafunc = $5.u;
+ bcopy(&$5.a, &nat->in_nsrc.na_addr[0],
+ sizeof($5.a));
+ bcopy(&$5.m, &nat->in_nsrc.na_addr[1],
+ sizeof($5.a));
+
+ setmapifnames();
+ }
+ | no mapit ifnames addr setproto ';'
+ { if (nat->in_v[0] == 0)
+ nat->in_v[0] = $4.v;
+ nat->in_osrcatype = $4.t;
+ bcopy(&$4.a, &nat->in_osrc.na_addr[0],
+ sizeof($4.a));
+ bcopy(&$4.m, &nat->in_osrc.na_addr[1],
+ sizeof($4.a));
+
+ setmapifnames();
}
- | mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions
- { nat->in_v = 4;
- nat->in_inip = $3.a.s_addr;
- nat->in_inmsk = $3.m.s_addr;
- nat->in_outip = $5.a.s_addr;
- nat->in_outmsk = $5.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
- if (((nat->in_redir & NAT_MAPBLK) != 0) ||
- ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
- nat_setgroupmap(nat);
+ | mapit ifnames mapfrom tlate rhsaddr proxy mapoptions
+ { if ($3 != 0 && $5.f != 0 && $3 != $5.f)
+ yyerror("5.address family mismatch");
+ if (nat->in_v[0] == 0 && $5.v != 0)
+ nat->in_v[0] = $5.v;
+ else if (nat->in_v[0] == 0 && $3 != 0)
+ nat->in_v[0] = ftov($3);
+ if (nat->in_v[1] == 0 && $5.v != 0)
+ nat->in_v[1] = $5.v;
+ else if (nat->in_v[1] == 0 && $3 != 0)
+ nat->in_v[1] = ftov($3);
+ nat->in_nsrcatype = $5.t;
+ nat->in_nsrcafunc = $5.u;
+ bcopy(&$5.a, &nat->in_nsrc.na_addr[0],
+ sizeof($5.a));
+ bcopy(&$5.m, &nat->in_nsrc.na_addr[1],
+ sizeof($5.a));
+
+ setmapifnames();
}
- | mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions
- { nat->in_v = 4;
- nat->in_outip = $5.a.s_addr;
- nat->in_outmsk = $5.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
- if ((suggest_port == 1) &&
- (nat->in_flags & IPN_TCPUDP) == 0)
- nat->in_flags |= IPN_TCPUDP;
- if ((nat->in_flags & IPN_TCPUDP) == 0)
- setnatproto(nat->in_p);
- if (((nat->in_redir & NAT_MAPBLK) != 0) ||
- ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
- nat_setgroupmap(nat);
+ | no mapit ifnames mapfrom setproto ';'
+ { nat->in_v[0] = ftov($4);
+ setmapifnames();
}
- | mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions
- { nat->in_v = 4;
- nat->in_outip = $5.a.s_addr;
- nat->in_outmsk = $5.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
- if ((suggest_port == 1) &&
- (nat->in_flags & IPN_TCPUDP) == 0)
- nat->in_flags |= IPN_TCPUDP;
- if (((nat->in_redir & NAT_MAPBLK) != 0) ||
- ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
- nat_setgroupmap(nat);
+ | mapit ifnames mapfrom tlate rhsaddr mapport mapoptions
+ { if ($3 != 0 && $5.f != 0 && $3 != $5.f)
+ yyerror("6.address family mismatch");
+ if (nat->in_v[0] == 0 && $5.v != 0)
+ nat->in_v[0] = $5.v;
+ else if (nat->in_v[0] == 0 && $3 != 0)
+ nat->in_v[0] = ftov($3);
+ if (nat->in_v[1] == 0 && $5.v != 0)
+ nat->in_v[1] = $5.v;
+ else if (nat->in_v[1] == 0 && $3 != 0)
+ nat->in_v[1] = ftov($3);
+ nat->in_nsrcatype = $5.t;
+ nat->in_nsrcafunc = $5.u;
+ bcopy(&$5.a, &nat->in_nsrc.na_addr[0],
+ sizeof($5.a));
+ bcopy(&$5.m, &nat->in_nsrc.na_addr[1],
+ sizeof($5.a));
+
+ setmapifnames();
}
;
mapblock:
- mapblockit ifnames addr IPNY_TLATE addr ports mapoptions
- { nat->in_v = 4;
- nat->in_inip = $3.a.s_addr;
- nat->in_inmsk = $3.m.s_addr;
- nat->in_outip = $5.a.s_addr;
- nat->in_outmsk = $5.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
- if ((nat->in_flags & IPN_TCPUDP) == 0)
- setnatproto(nat->in_p);
- if (((nat->in_redir & NAT_MAPBLK) != 0) ||
- ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
- nat_setgroupmap(nat);
+ mapblockit ifnames addr tlate addr ports mapoptions
+ { if ($3.f != 0 && $5.f != 0 && $3.f != $5.f)
+ yyerror("7.address family mismatch");
+ if (nat->in_v[0] == 0 && $5.v != 0)
+ nat->in_v[0] = $5.v;
+ else if (nat->in_v[0] == 0 && $3.v != 0)
+ nat->in_v[0] = $3.v;
+ if (nat->in_v[1] == 0 && $5.v != 0)
+ nat->in_v[1] = $5.v;
+ else if (nat->in_v[1] == 0 && $3.v != 0)
+ nat->in_v[1] = $3.v;
+ nat->in_osrcatype = $3.t;
+ bcopy(&$3.a, &nat->in_osrc.na_addr[0],
+ sizeof($3.a));
+ bcopy(&$3.m, &nat->in_osrc.na_addr[1],
+ sizeof($3.a));
+ nat->in_nsrcatype = $5.t;
+ nat->in_nsrcafunc = $5.u;
+ bcopy(&$5.a, &nat->in_nsrc.na_addr[0],
+ sizeof($5.a));
+ bcopy(&$5.m, &nat->in_nsrc.na_addr[1],
+ sizeof($5.a));
+
+ setmapifnames();
+ }
+ | no mapblockit ifnames { yyexpectaddr = 1; } addr setproto ';'
+ { if (nat->in_v[0] == 0)
+ nat->in_v[0] = $5.v;
+ if (nat->in_v[1] == 0)
+ nat->in_v[1] = $5.v;
+ nat->in_osrcatype = $5.t;
+ bcopy(&$5.a, &nat->in_osrc.na_addr[0],
+ sizeof($5.a));
+ bcopy(&$5.m, &nat->in_osrc.na_addr[1],
+ sizeof($5.a));
+
+ setmapifnames();
}
;
-redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions
- { nat->in_v = 4;
- nat->in_outip = $3.a.s_addr;
- nat->in_outmsk = $3.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
- if ((nat->in_p == 0) &&
- ((nat->in_flags & IPN_TCPUDP) == 0) &&
- (nat->in_pmin != 0 ||
- nat->in_pmax != 0 ||
- nat->in_pnext != 0))
- setnatproto(IPPROTO_TCP);
+redir: rdrit ifnames addr dport tlate dip nport setproto rdroptions
+ { if ($6 != 0 && $3.f != 0 && $6 != $3.f)
+ yyerror("21.address family mismatch");
+ if (nat->in_v[0] == 0) {
+ if ($3.v != AF_UNSPEC)
+ nat->in_v[0] = ftov($3.f);
+ else
+ nat->in_v[0] = ftov($6);
+ }
+ nat->in_odstatype = $3.t;
+ bcopy(&$3.a, &nat->in_odst.na_addr[0],
+ sizeof($3.a));
+ bcopy(&$3.m, &nat->in_odst.na_addr[1],
+ sizeof($3.a));
+
+ setrdrifnames();
}
- | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions
- { nat->in_v = 4;
- if ((nat->in_p == 0) &&
- ((nat->in_flags & IPN_TCPUDP) == 0) &&
- (nat->in_pmin != 0 ||
- nat->in_pmax != 0 ||
- nat->in_pnext != 0))
- setnatproto(IPPROTO_TCP);
- if ((suggest_port == 1) &&
- (nat->in_flags & IPN_TCPUDP) == 0)
- nat->in_flags |= IPN_TCPUDP;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
+ | no rdrit ifnames addr dport setproto ';'
+ { if (nat->in_v[0] == 0)
+ nat->in_v[0] = ftov($4.f);
+ nat->in_odstatype = $4.t;
+ bcopy(&$4.a, &nat->in_odst.na_addr[0],
+ sizeof($4.a));
+ bcopy(&$4.m, &nat->in_odst.na_addr[1],
+ sizeof($4.a));
+
+ setrdrifnames();
}
- | rdrit ifnames addr IPNY_TLATE dip setproto rdroptions
- { nat->in_v = 4;
- nat->in_outip = $3.a.s_addr;
- nat->in_outmsk = $3.m.s_addr;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
+ | rdrit ifnames rdrfrom tlate dip nport setproto rdroptions
+ { if ($5 != 0 && $3 != 0 && $5 != $3)
+ yyerror("20.address family mismatch");
+ if (nat->in_v[0] == 0) {
+ if ($3 != AF_UNSPEC)
+ nat->in_v[0] = ftov($3);
+ else
+ nat->in_v[0] = ftov($5);
+ }
+ setrdrifnames();
+ }
+ | no rdrit ifnames rdrfrom setproto ';'
+ { nat->in_v[0] = ftov($4);
+
+ setrdrifnames();
}
- | rdrit ifnames rdrfrom IPNY_TLATE dip setproto rdroptions
- { nat->in_v = 4;
- if ((suggest_port == 1) &&
- (nat->in_flags & IPN_TCPUDP) == 0)
- nat->in_flags |= IPN_TCPUDP;
- if (nat->in_ifnames[1][0] == '\0')
- strncpy(nat->in_ifnames[1],
- nat->in_ifnames[0],
- sizeof(nat->in_ifnames[0]));
+ ;
+
+rewrite:
+ IPNY_REWRITE oninout rwrproto mapfrom tlate newdst newopts
+ { if (nat->in_v[0] == 0)
+ nat->in_v[0] = ftov($4);
+ if (nat->in_redir & NAT_MAP)
+ setmapifnames();
+ else
+ setrdrifnames();
+ nat->in_redir |= NAT_REWRITE;
+ }
+ ;
+
+divert: IPNY_DIVERT oninout rwrproto mapfrom tlate divdst newopts
+ { if (nat->in_v[0] == 0)
+ nat->in_v[0] = ftov($4);
+ if (nat->in_redir & NAT_MAP) {
+ setmapifnames();
+ nat->in_pr[0] = IPPROTO_UDP;
+ } else {
+ setrdrifnames();
+ nat->in_pr[1] = IPPROTO_UDP;
+ }
+ nat->in_flags &= ~IPN_TCP;
+ }
+ ;
+
+tlate: IPNY_TLATE { yyexpectaddr = 1; }
+ ;
+
+pconf: IPNY_PROXY { yysetdict(proxies); }
+ IPNY_DNS '/' proto IPNY_CONFIG YY_STR '{'
+ { proxy_setconfig(IPNY_DNS); }
+ dnslines ';' '}'
+ { proxy_addconfig("dns", $5, $7, $10);
+ proxy_unsetconfig();
+ }
+ ;
+
+dnslines:
+ dnsline { $$ = $1; }
+ | dnslines ';' dnsline { $$ = $1; $1->na_next = $3; }
+ ;
+
+dnsline:
+ IPNY_ALLOW YY_STR { $$ = proxy_dns_add_pass(NULL, $2); }
+ | IPNY_DENY YY_STR { $$ = proxy_dns_add_block(NULL, $2); }
+ | IPNY_ALLOW '.' YY_STR { $$ = proxy_dns_add_pass(".", $3); }
+ | IPNY_DENY '.' YY_STR { $$ = proxy_dns_add_block(".", $3); }
+ ;
+
+oninout:
+ inout IPNY_ON ifnames { ; }
+ ;
+
+inout: IPNY_IN { nat->in_redir = NAT_REDIRECT; }
+ | IPNY_OUT { nat->in_redir = NAT_MAP; }
+ ;
+
+rwrproto:
+ | IPNY_PROTO setproto
+ ;
+
+newdst: src rhsaddr srcports dst erhdaddr dstports
+ { nat->in_nsrc.na_addr[0] = $2.a;
+ nat->in_nsrc.na_addr[1] = $2.m;
+ nat->in_nsrc.na_atype = $2.t;
+ if ($2.t == FRI_LOOKUP) {
+ nat->in_nsrc.na_type = $2.u;
+ nat->in_nsrc.na_subtype = $2.s;
+ nat->in_nsrc.na_num = $2.n;
+ }
+ nat->in_nsports[0] = $3.p1;
+ nat->in_nsports[1] = $3.p2;
+ nat->in_ndst.na_addr[0] = $5.a;
+ nat->in_ndst.na_addr[1] = $5.m;
+ nat->in_ndst.na_atype = $5.t;
+ if ($5.t == FRI_LOOKUP) {
+ nat->in_ndst.na_type = $5.u;
+ nat->in_ndst.na_subtype = $5.s;
+ nat->in_ndst.na_num = $5.n;
+ }
+ nat->in_ndports[0] = $6.p1;
+ nat->in_ndports[1] = $6.p2;
+ }
+ ;
+
+divdst: src addr ',' portspec dst addr ',' portspec IPNY_UDP
+ { nat->in_nsrc.na_addr[0] = $2.a;
+ if ($2.m.in4.s_addr != 0xffffffff)
+ yyerror("divert must have /32 dest");
+ nat->in_nsrc.na_addr[1] = $2.m;
+ nat->in_nsports[0] = $4;
+ nat->in_nsports[1] = $4;
+
+ nat->in_ndst.na_addr[0] = $6.a;
+ nat->in_ndst.na_addr[1] = $6.m;
+ if ($6.m.in4.s_addr != 0xffffffff)
+ yyerror("divert must have /32 dest");
+ nat->in_ndports[0] = $8;
+ nat->in_ndports[1] = $8;
+
+ nat->in_redir |= NAT_DIVERTUDP;
+ }
+ ;
+
+src: IPNY_SRC { yyexpectaddr = 1; }
+ ;
+
+dst: IPNY_DST { yyexpectaddr = 1; }
+ ;
+
+srcports:
+ comaports { $$.p1 = $1.p1;
+ $$.p2 = $1.p2;
+ }
+ | IPNY_PORT '=' portspec
+ { $$.p1 = $3;
+ $$.p2 = $3;
+ nat->in_flags |= IPN_FIXEDSPORT;
+ }
+ ;
+
+dstports:
+ comaports { $$.p1 = $1.p1;
+ $$.p2 = $1.p2;
+ }
+ | IPNY_PORT '=' portspec
+ { $$.p1 = $3;
+ $$.p2 = $3;
+ nat->in_flags |= IPN_FIXEDDPORT;
+ }
+ ;
+
+comaports:
+ { $$.p1 = 0;
+ $$.p2 = 0;
+ }
+ | ',' { if (!(nat->in_flags & IPN_TCPUDP))
+ yyerror("must be TCP/UDP for ports");
+ }
+ portpair { $$.p1 = $3.p1;
+ $$.p2 = $3.p2;
}
;
proxy: | IPNY_PROXY port portspec YY_STR '/' proto
- { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
+ { int pos;
+ pos = addname(&nat, $4);
+ nat->in_plabel = pos;
if (nat->in_dcmp == 0) {
- nat->in_dport = htons($3);
- } else if ($3 != nat->in_dport) {
+ nat->in_odport = $3;
+ } else if ($3 != nat->in_odport) {
yyerror("proxy port numbers not consistant");
}
+ nat->in_ndport = $3;
setnatproto($6);
free($4);
}
| IPNY_PROXY port YY_STR YY_STR '/' proto
- { int pnum;
- strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
+ { int pnum, pos;
+ pos = addname(&nat, $4);
+ nat->in_plabel = pos;
pnum = getportproto($3, $6);
if (pnum == -1)
yyerror("invalid port number");
- nat->in_dport = pnum;
+ nat->in_odport = ntohs(pnum);
+ nat->in_ndport = ntohs(pnum);
setnatproto($6);
free($3);
free($4);
}
+ | IPNY_PROXY port portspec YY_STR '/' proto IPNY_CONFIG YY_STR
+ { int pos;
+ pos = addname(&nat, $4);
+ nat->in_plabel = pos;
+ if (nat->in_dcmp == 0) {
+ nat->in_odport = $3;
+ } else if ($3 != nat->in_odport) {
+ yyerror("proxy port numbers not consistant");
+ }
+ nat->in_ndport = $3;
+ setnatproto($6);
+ nat->in_pconfig = addname(&nat, $8);
+ free($4);
+ free($8);
+ }
+ | IPNY_PROXY port YY_STR YY_STR '/' proto IPNY_CONFIG YY_STR
+ { int pnum, pos;
+ pos = addname(&nat, $4);
+ nat->in_plabel = pos;
+ pnum = getportproto($3, $6);
+ if (pnum == -1)
+ yyerror("invalid port number");
+ nat->in_odport = ntohs(pnum);
+ nat->in_ndport = ntohs(pnum);
+ setnatproto($6);
+ pos = addname(&nat, $8);
+ nat->in_pconfig = pos;
+ free($3);
+ free($4);
+ free($8);
+ }
;
-
setproto:
- | proto { if (nat->in_p != 0 ||
+ | proto { if (nat->in_pr[0] != 0 ||
+ nat->in_pr[1] != 0 ||
nat->in_flags & IPN_TCPUDP)
yyerror("protocol set twice");
setnatproto($1);
}
- | IPNY_TCPUDP { if (nat->in_p != 0 ||
+ | IPNY_TCPUDP { if (nat->in_pr[0] != 0 ||
+ nat->in_pr[1] != 0 ||
nat->in_flags & IPN_TCPUDP)
yyerror("protocol set twice");
nat->in_flags |= IPN_TCPUDP;
- nat->in_p = 0;
+ nat->in_pr[0] = 0;
+ nat->in_pr[1] = 0;
}
- | IPNY_TCP '/' IPNY_UDP { if (nat->in_p != 0 ||
+ | IPNY_TCP '/' IPNY_UDP { if (nat->in_pr[0] != 0 ||
+ nat->in_pr[1] != 0 ||
nat->in_flags & IPN_TCPUDP)
yyerror("protocol set twice");
nat->in_flags |= IPN_TCPUDP;
- nat->in_p = 0;
+ nat->in_pr[0] = 0;
+ nat->in_pr[1] = 0;
}
;
-rhaddr: addr { $$.a = $1.a; $$.m = $1.m; }
- | IPNY_RANGE ipv4 '-' ipv4
- { $$.a = $2; $$.m = $4;
- nat->in_flags |= IPN_IPRANGE; }
+rhsaddr:
+ addr { $$ = $1;
+ yyexpectaddr = 0;
+ }
+ | hostname '-' { yyexpectaddr = 1; } hostname
+ { $$.t = FRI_RANGE;
+ if ($1.f != $4.f)
+ yyerror("8.address family "
+ "mismatch");
+ $$.f = $1.f;
+ $$.v = ftov($1.f);
+ $$.a = $1.a;
+ $$.m = $4.a;
+ nat->in_flags |= IPN_SIPRANGE;
+ yyexpectaddr = 0;
+ }
+ | IPNY_RANGE hostname '-' { yyexpectaddr = 1; } hostname
+ { $$.t = FRI_RANGE;
+ if ($2.f != $5.f)
+ yyerror("9.address family "
+ "mismatch");
+ $$.f = $2.f;
+ $$.v = ftov($2.f);
+ $$.a = $2.a;
+ $$.m = $5.a;
+ nat->in_flags |= IPN_SIPRANGE;
+ yyexpectaddr = 0;
+ }
;
dip:
- hostname { nat->in_inip = $1.s_addr;
- nat->in_inmsk = 0xffffffff; }
- | hostname '/' YY_NUMBER { if ($3 != 0 || $1.s_addr != 0)
- yyerror("Only 0/0 supported");
- nat->in_inip = 0;
- nat->in_inmsk = 0;
+ hostname ',' { yyexpectaddr = 1; } hostname
+ { nat->in_flags |= IPN_SPLIT;
+ if ($1.f != $4.f)
+ yyerror("10.address family "
+ "mismatch");
+ $$ = $1.f;
+ nat->in_ndstip6 = $1.a;
+ nat->in_ndstmsk6 = $4.a;
+ nat->in_ndstatype = FRI_SPLIT;
+ yyexpectaddr = 0;
+ }
+ | rhdaddr { int bits;
+ nat->in_ndstip6 = $1.a;
+ nat->in_ndstmsk6 = $1.m;
+ nat->in_ndst.na_atype = $1.t;
+ yyexpectaddr = 0;
+ if ($1.f == AF_INET)
+ bits = count4bits($1.m.in4.s_addr);
+ else
+ bits = count6bits($1.m.i6);
+ if (($1.f == AF_INET) && (bits != 0) &&
+ (bits != 32)) {
+ yyerror("dest ip bitmask not /32");
+ } else if (($1.f == AF_INET6) &&
+ (bits != 0) && (bits != 128)) {
+ yyerror("dest ip bitmask not /128");
+ }
+ $$ = $1.f;
+ }
+ ;
+
+rhdaddr:
+ addr { $$ = $1;
+ yyexpectaddr = 0;
+ }
+ | hostname '-' hostname { bzero(&$$, sizeof($$));
+ $$.t = FRI_RANGE;
+ if ($1.f != 0 && $3.f != 0 &&
+ $1.f != $3.f)
+ yyerror("11.address family "
+ "mismatch");
+ $$.a = $1.a;
+ $$.m = $3.a;
+ nat->in_flags |= IPN_DIPRANGE;
+ yyexpectaddr = 0;
+ }
+ | IPNY_RANGE hostname '-' hostname
+ { bzero(&$$, sizeof($$));
+ $$.t = FRI_RANGE;
+ if ($2.f != 0 && $4.f != 0 &&
+ $2.f != $4.f)
+ yyerror("12.address family "
+ "mismatch");
+ $$.a = $2.a;
+ $$.m = $4.a;
+ nat->in_flags |= IPN_DIPRANGE;
+ yyexpectaddr = 0;
+ }
+ ;
+
+erhdaddr:
+ rhdaddr { $$ = $1; }
+ | IPNY_DSTLIST '/' YY_NUMBER { $$.t = FRI_LOOKUP;
+ $$.u = IPLT_DSTLIST;
+ $$.s = 0;
+ $$.n = $3;
+ }
+ | IPNY_DSTLIST '/' YY_STR { $$.t = FRI_LOOKUP;
+ $$.u = IPLT_DSTLIST;
+ $$.s = 1;
+ $$.n = addname(&nat, $3);
}
- | hostname ',' hostname { nat->in_flags |= IPN_SPLIT;
- nat->in_inip = $1.s_addr;
- nat->in_inmsk = $3.s_addr; }
;
port: IPNY_PORT { suggest_port = 1; }
@@ -347,27 +726,44 @@ portspec:
else
$$ = $1;
}
- | YY_STR { if (getport(NULL, $1, &($$)) == -1)
+ | YY_STR { if (getport(NULL, $1,
+ &($$), NULL) == -1)
yyerror("invalid port number");
$$ = ntohs($$);
}
;
-dport: | port portspec { nat->in_pmin = htons($2);
- nat->in_pmax = htons($2); }
- | port portspec '-' portspec { nat->in_pmin = htons($2);
- nat->in_pmax = htons($4); }
- | port portspec ':' portspec { nat->in_pmin = htons($2);
- nat->in_pmax = htons($4); }
+portpair:
+ portspec { $$.p1 = $1; $$.p2 = $1; }
+ | portspec '-' portspec { $$.p1 = $1; $$.p2 = $3; }
+ | portspec ':' portspec { $$.p1 = $1; $$.p2 = $3; }
;
-nport: port portspec { nat->in_pnext = htons($2); }
- | port '=' portspec { nat->in_pnext = htons($3);
+dport: | port portpair { nat->in_odport = $2.p1;
+ if ($2.p2 == 0)
+ nat->in_dtop = $2.p1;
+ else
+ nat->in_dtop = $2.p2;
+ }
+ ;
+
+nport: | port portpair { nat->in_dpmin = $2.p1;
+ nat->in_dpnext = $2.p1;
+ nat->in_dpmax = $2.p2;
+ nat->in_ndport = $2.p1;
+ if (nat->in_dtop == 0)
+ nat->in_dtop = $2.p2;
+ }
+ | port '=' portspec { nat->in_dpmin = $3;
+ nat->in_dpnext = $3;
+ nat->in_ndport = $3;
+ if (nat->in_dtop == 0)
+ nat->in_dtop = nat->in_odport;
nat->in_flags |= IPN_FIXEDDPORT;
}
;
-ports: | IPNY_PORTS YY_NUMBER { nat->in_pmin = $2; }
+ports: | IPNY_PORTS YY_NUMBER { nat->in_spmin = $2; }
| IPNY_PORTS IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; }
;
@@ -383,128 +779,282 @@ mapblockit:
;
mapfrom:
- from sobject IPNY_TO dobject
- | from sobject '!' IPNY_TO dobject
- { nat->in_flags |= IPN_NOTDST; }
- | from sobject IPNY_TO '!' dobject
- { nat->in_flags |= IPN_NOTDST; }
+ from sobject to dobject { if ($2 != 0 && $4 != 0 && $2 != $4)
+ yyerror("13.address family "
+ "mismatch");
+ $$ = $2;
+ }
+ | from sobject '!' to dobject
+ { if ($2 != 0 && $5 != 0 && $2 != $5)
+ yyerror("14.address family "
+ "mismatch");
+ nat->in_flags |= IPN_NOTDST;
+ $$ = $2;
+ }
+ | from sobject to '!' dobject
+ { if ($2 != 0 && $5 != 0 && $2 != $5)
+ yyerror("15.address family "
+ "mismatch");
+ nat->in_flags |= IPN_NOTDST;
+ $$ = $2;
+ }
;
rdrfrom:
- from sobject IPNY_TO dobject
- | '!' from sobject IPNY_TO dobject
- { nat->in_flags |= IPN_NOTSRC; }
- | from '!' sobject IPNY_TO dobject
- { nat->in_flags |= IPN_NOTSRC; }
+ from sobject to dobject { if ($2 != 0 && $4 != 0 && $2 != $4)
+ yyerror("16.address family "
+ "mismatch");
+ $$ = $2;
+ }
+ | '!' from sobject to dobject
+ { if ($3 != 0 && $5 != 0 && $3 != $5)
+ yyerror("17.address family "
+ "mismatch");
+ nat->in_flags |= IPN_NOTSRC;
+ $$ = $3;
+ }
+ | from '!' sobject to dobject
+ { if ($3 != 0 && $5 != 0 && $3 != $5)
+ yyerror("18.address family "
+ "mismatch");
+ nat->in_flags |= IPN_NOTSRC;
+ $$ = $3;
+ }
;
-from: IPNY_FROM { nat->in_flags |= IPN_FILTER; }
+from: IPNY_FROM { nat->in_flags |= IPN_FILTER;
+ yyexpectaddr = 1;
+ }
+ ;
+
+to: IPNY_TO { yyexpectaddr = 1; }
;
ifnames:
- ifname
- | ifname ',' otherifname
+ ifname family { yyexpectaddr = 1; }
+ | ifname ',' otherifname family { yyexpectaddr = 1; }
;
-ifname: YY_STR { strncpy(nat->in_ifnames[0], $1,
- sizeof(nat->in_ifnames[0]));
- nat->in_ifnames[0][LIFNAMSIZ - 1] = '\0';
- free($1);
- }
+ifname: YY_STR { setifname(&nat, 0, $1);
+ free($1);
+ }
+ ;
+
+family: | IPNY_INET { nat->in_v[0] = 4; nat->in_v[1] = 4; }
+ | IPNY_INET6 { nat->in_v[0] = 6; nat->in_v[1] = 6; }
;
otherifname:
- YY_STR { strncpy(nat->in_ifnames[1], $1,
- sizeof(nat->in_ifnames[1]));
- nat->in_ifnames[1][LIFNAMSIZ - 1] = '\0';
- free($1);
- }
+ YY_STR { setifname(&nat, 1, $1);
+ free($1);
+ }
;
mapport:
- IPNY_PORTMAP tcpudp portspec ':' portspec randport
- { nat->in_pmin = htons($3);
- nat->in_pmax = htons($5);
- }
- | IPNY_PORTMAP tcpudp IPNY_AUTO randport
- { nat->in_flags |= IPN_AUTOPORTMAP;
- nat->in_pmin = htons(1024);
- nat->in_pmax = htons(65535);
- }
- | IPNY_ICMPIDMAP YY_STR YY_NUMBER ':' YY_NUMBER
- { if (strcmp($2, "icmp") != 0) {
+ IPNY_PORTMAP tcpudp portpair sequential
+ { nat->in_spmin = $3.p1;
+ nat->in_spmax = $3.p2;
+ }
+ | IPNY_PORTMAP portpair tcpudp sequential
+ { nat->in_spmin = $2.p1;
+ nat->in_spmax = $2.p2;
+ }
+ | IPNY_PORTMAP tcpudp IPNY_AUTO sequential
+ { nat->in_flags |= IPN_AUTOPORTMAP;
+ nat->in_spmin = 1024;
+ nat->in_spmax = 65535;
+ }
+ | IPNY_ICMPIDMAP YY_STR portpair sequential
+ { if (strcmp($2, "icmp") != 0 &&
+ strcmp($2, "ipv6-icmp") != 0) {
yyerror("icmpidmap not followed by icmp");
}
free($2);
- if ($3 < 0 || $3 > 65535)
+ if ($3.p1 < 0 || $3.p1 > 65535)
yyerror("invalid ICMP Id number");
- if ($5 < 0 || $5 > 65535)
+ if ($3.p2 < 0 || $3.p2 > 65535)
yyerror("invalid ICMP Id number");
+ if (strcmp($2, "ipv6-icmp") == 0) {
+ nat->in_pr[0] = IPPROTO_ICMPV6;
+ nat->in_pr[1] = IPPROTO_ICMPV6;
+ } else {
+ nat->in_pr[0] = IPPROTO_ICMP;
+ nat->in_pr[1] = IPPROTO_ICMP;
+ }
nat->in_flags = IPN_ICMPQUERY;
- nat->in_pmin = htons($3);
- nat->in_pmax = htons($5);
+ nat->in_spmin = $3.p1;
+ nat->in_spmax = $3.p2;
}
;
-randport:
- | IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; }
- ;
-
sobject:
- saddr
- | saddr port portstuff { nat->in_sport = $3.p1;
+ saddr { $$ = $1; }
+ | saddr port portstuff { nat->in_osport = $3.p1;
nat->in_stop = $3.p2;
- nat->in_scmp = $3.pc; }
+ nat->in_scmp = $3.pc;
+ $$ = $1;
+ }
;
-saddr: addr { if (nat->in_redir == NAT_REDIRECT) {
- nat->in_srcip = $1.a.s_addr;
- nat->in_srcmsk = $1.m.s_addr;
- } else {
- nat->in_inip = $1.a.s_addr;
- nat->in_inmsk = $1.m.s_addr;
- }
+saddr: addr { nat->in_osrcatype = $1.t;
+ bcopy(&$1.a,
+ &nat->in_osrc.na_addr[0],
+ sizeof($1.a));
+ bcopy(&$1.m,
+ &nat->in_osrc.na_addr[1],
+ sizeof($1.m));
+ $$ = $1.f;
}
;
dobject:
- daddr
- | daddr port portstuff { nat->in_dport = $3.p1;
+ daddr { $$ = $1; }
+ | daddr port portstuff { nat->in_odport = $3.p1;
nat->in_dtop = $3.p2;
nat->in_dcmp = $3.pc;
- if (nat->in_redir == NAT_REDIRECT)
- nat->in_pmin = htons($3.p1);
+ $$ = $1;
}
;
-daddr: addr { if (nat->in_redir == NAT_REDIRECT) {
- nat->in_outip = $1.a.s_addr;
- nat->in_outmsk = $1.m.s_addr;
- } else {
- nat->in_srcip = $1.a.s_addr;
- nat->in_srcmsk = $1.m.s_addr;
+daddr: addr { nat->in_odstatype = $1.t;
+ bcopy(&$1.a,
+ &nat->in_odst.na_addr[0],
+ sizeof($1.a));
+ bcopy(&$1.m,
+ &nat->in_odst.na_addr[1],
+ sizeof($1.m));
+ $$ = $1.f;
+ }
+ ;
+
+addr: IPNY_ANY { yyexpectaddr = 0;
+ bzero(&$$, sizeof($$));
+ $$.t = FRI_NORMAL;
+ }
+ | hostname { bzero(&$$, sizeof($$));
+ $$.a = $1.a;
+ $$.t = FRI_NORMAL;
+ $$.v = ftov($1.f);
+ $$.f = $1.f;
+ if ($$.f == AF_INET) {
+ $$.m.in4.s_addr = 0xffffffff;
+ } else if ($$.f == AF_INET6) {
+ $$.m.i6[0] = 0xffffffff;
+ $$.m.i6[1] = 0xffffffff;
+ $$.m.i6[2] = 0xffffffff;
+ $$.m.i6[3] = 0xffffffff;
+ }
+ yyexpectaddr = 0;
+ }
+ | hostname slash YY_NUMBER
+ { bzero(&$$, sizeof($$));
+ $$.a = $1.a;
+ $$.f = $1.f;
+ $$.v = ftov($1.f);
+ $$.t = FRI_NORMAL;
+ ntomask($$.f, $3, (u_32_t *)&$$.m);
+ $$.a.i6[0] &= $$.m.i6[0];
+ $$.a.i6[1] &= $$.m.i6[1];
+ $$.a.i6[2] &= $$.m.i6[2];
+ $$.a.i6[3] &= $$.m.i6[3];
+ yyexpectaddr = 0;
+ }
+ | hostname slash ipaddr { bzero(&$$, sizeof($$));
+ if ($1.f != $3.f) {
+ yyerror("1.address family "
+ "mismatch");
+ }
+ $$.a = $1.a;
+ $$.m = $3.a;
+ $$.t = FRI_NORMAL;
+ $$.a.i6[0] &= $$.m.i6[0];
+ $$.a.i6[1] &= $$.m.i6[1];
+ $$.a.i6[2] &= $$.m.i6[2];
+ $$.a.i6[3] &= $$.m.i6[3];
+ $$.f = $1.f;
+ $$.v = ftov($1.f);
+ yyexpectaddr = 0;
+ }
+ | hostname slash hexnumber { bzero(&$$, sizeof($$));
+ $$.a = $1.a;
+ $$.m.in4.s_addr = htonl($3);
+ $$.t = FRI_NORMAL;
+ $$.a.in4.s_addr &= $$.m.in4.s_addr;
+ $$.f = $1.f;
+ $$.v = ftov($1.f);
+ if ($$.f == AF_INET6)
+ yyerror("incorrect inet6 mask");
+ }
+ | hostname mask ipaddr { bzero(&$$, sizeof($$));
+ if ($1.f != $3.f) {
+ yyerror("2.address family "
+ "mismatch");
}
+ $$.a = $1.a;
+ $$.m = $3.a;
+ $$.t = FRI_NORMAL;
+ $$.a.i6[0] &= $$.m.i6[0];
+ $$.a.i6[1] &= $$.m.i6[1];
+ $$.a.i6[2] &= $$.m.i6[2];
+ $$.a.i6[3] &= $$.m.i6[3];
+ $$.f = $1.f;
+ $$.v = ftov($1.f);
+ yyexpectaddr = 0;
+ }
+ | hostname mask hexnumber { bzero(&$$, sizeof($$));
+ $$.a = $1.a;
+ $$.m.in4.s_addr = htonl($3);
+ $$.t = FRI_NORMAL;
+ $$.a.in4.s_addr &= $$.m.in4.s_addr;
+ $$.f = AF_INET;
+ $$.v = 4;
+ }
+ | pool slash YY_NUMBER { bzero(&$$, sizeof($$));
+ $$.a.iplookupnum = $3;
+ $$.a.iplookuptype = IPLT_POOL;
+ $$.a.iplookupsubtype = 0;
+ $$.t = FRI_LOOKUP;
+ }
+ | pool slash YY_STR { bzero(&$$, sizeof($$));
+ $$.a.iplookupname = addname(&nat,$3);
+ $$.a.iplookuptype = IPLT_POOL;
+ $$.a.iplookupsubtype = 1;
+ $$.t = FRI_LOOKUP;
+ }
+ | hash slash YY_NUMBER { bzero(&$$, sizeof($$));
+ $$.a.iplookupnum = $3;
+ $$.a.iplookuptype = IPLT_HASH;
+ $$.a.iplookupsubtype = 0;
+ $$.t = FRI_LOOKUP;
+ }
+ | hash slash YY_STR { bzero(&$$, sizeof($$));
+ $$.a.iplookupname = addname(&nat,$3);
+ $$.a.iplookuptype = IPLT_HASH;
+ $$.a.iplookupsubtype = 1;
+ $$.t = FRI_LOOKUP;
}
;
-addr: IPNY_ANY { $$.a.s_addr = 0; $$.m.s_addr = 0; }
- | nummask { $$.a = $1.a; $$.m = $1.m;
- $$.a.s_addr &= $$.m.s_addr; }
- | hostname '/' ipv4 { $$.a = $1; $$.m = $3;
- $$.a.s_addr &= $$.m.s_addr; }
- | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = htonl($3);
- $$.a.s_addr &= $$.m.s_addr; }
- | hostname IPNY_MASK ipv4 { $$.a = $1; $$.m = $3;
- $$.a.s_addr &= $$.m.s_addr; }
- | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = htonl($3);
- $$.a.s_addr &= $$.m.s_addr; }
+slash: '/' { yyexpectaddr = 0; }
;
-nummask:
- hostname { $$.a = $1;
- $$.m.s_addr = 0xffffffff; }
- | hostname '/' YY_NUMBER { $$.a = $1;
- ntomask(4, $3, &$$.m.s_addr); }
+mask: IPNY_MASK { yyexpectaddr = 0; }
+ ;
+
+pool: IPNY_POOL { if (!(nat->in_flags & IPN_FILTER)) {
+ yyerror("Can only use pool with from/to rules\n");
+ }
+ yyexpectaddr = 0;
+ yyresetdict();
+ }
+ ;
+
+hash: IPNY_HASH { if (!(nat->in_flags & IPN_FILTER)) {
+ yyerror("Can only use hash with from/to rules\n");
+ }
+ yyexpectaddr = 0;
+ yyresetdict();
+ }
;
portstuff:
@@ -513,17 +1063,16 @@ portstuff:
;
mapoptions:
- rr frag age mssclamp nattag setproto
+ rr frag age mssclamp nattag setproto purge
;
rdroptions:
- rr frag age sticky mssclamp rdrproxy nattag
+ rr frag age sticky mssclamp rdrproxy nattag purge
;
nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2,
sizeof(nat->in_tag.ipt_tag));
}
-
rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; }
;
@@ -536,9 +1085,9 @@ age: | IPNY_AGE YY_NUMBER { nat->in_age[0] = $2;
nat->in_age[1] = $4; }
;
-sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) &&
+sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) &&
!(nat->in_flags & IPN_SPLIT)) {
- fprintf(stderr,
+ FPRINTF(stderr,
"'sticky' for use with round-robin/IP splitting only\n");
} else
nat->in_flags |= IPN_STICKY;
@@ -549,30 +1098,47 @@ mssclamp:
| IPNY_MSSCLAMP YY_NUMBER { nat->in_mssclamp = $2; }
;
-tcpudp: | IPNY_TCP { setnatproto(IPPROTO_TCP); }
+tcpudp: IPNY_TCP { setnatproto(IPPROTO_TCP); }
| IPNY_UDP { setnatproto(IPPROTO_UDP); }
| IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP;
- nat->in_p = 0;
+ nat->in_pr[0] = 0;
+ nat->in_pr[1] = 0;
}
| IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP;
- nat->in_p = 0;
+ nat->in_pr[0] = 0;
+ nat->in_pr[1] = 0;
}
;
+sequential:
+ | IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; }
+ ;
+
+purge:
+ | IPNY_PURGE { nat->in_flags |= IPN_PURGE; }
+ ;
+
rdrproxy:
IPNY_PROXY YY_STR
- { strncpy(nat->in_plabel, $2,
- sizeof(nat->in_plabel));
- nat->in_dport = nat->in_pnext;
- nat->in_dport = htons(nat->in_dport);
+ { int pos;
+ pos = addname(&nat, $2);
+ nat->in_plabel = pos;
+ nat->in_odport = nat->in_dpnext;
+ nat->in_dtop = nat->in_odport;
free($2);
}
- | proxy { if (nat->in_plabel[0] != '\0') {
- nat->in_pmin = nat->in_dport;
- nat->in_pmax = nat->in_pmin;
- nat->in_pnext = nat->in_pmin;
- }
- }
+ | proxy { if (nat->in_plabel != -1) {
+ nat->in_ndport = nat->in_odport;
+ nat->in_dpmin = nat->in_odport;
+ nat->in_dpmax = nat->in_dpmin;
+ nat->in_dtop = nat->in_dpmin;
+ nat->in_dpnext = nat->in_dpmin;
+ }
+ }
+ ;
+
+newopts:
+ | IPNY_PURGE { nat->in_flags |= IPN_PURGE; }
;
proto: YY_NUMBER { $$ = $1;
@@ -582,7 +1148,10 @@ proto: YY_NUMBER { $$ = $1;
}
| IPNY_TCP { $$ = IPPROTO_TCP; }
| IPNY_UDP { $$ = IPPROTO_UDP; }
- | YY_STR { $$ = getproto($1); free($1);
+ | YY_STR { $$ = getproto($1);
+ free($1);
+ if ($$ == -1)
+ yyerror("unknwon protocol");
if ($$ != IPPROTO_TCP &&
$$ != IPPROTO_UDP)
suggest_port = 0;
@@ -594,14 +1163,39 @@ hexnumber:
;
hostname:
- YY_STR { if (gethost($1, &$$.s_addr) == -1)
- fprintf(stderr,
+ YY_STR { i6addr_t addr;
+
+ bzero(&$$, sizeof($$));
+ if (gethost(AF_INET, $1,
+ &addr) == 0) {
+ $$.a = addr;
+ $$.f = AF_INET;
+ } else
+ if (gethost(AF_INET6, $1,
+ &addr) == 0) {
+ $$.a = addr;
+ $$.f = AF_INET6;
+ } else {
+ FPRINTF(stderr,
"Unknown host '%s'\n",
$1);
+ }
free($1);
}
- | YY_NUMBER { $$.s_addr = htonl($1); }
- | ipv4 { $$.s_addr = $1.s_addr; }
+ | YY_NUMBER { bzero(&$$, sizeof($$));
+ $$.a.in4.s_addr = htonl($1);
+ if ($$.a.in4.s_addr != 0)
+ $$.f = AF_INET;
+ }
+ | ipv4 { $$ = $1; }
+ | YY_IPV6 { bzero(&$$, sizeof($$));
+ $$.a = $1;
+ $$.f = AF_INET6;
+ }
+ | YY_NUMBER YY_IPV6 { bzero(&$$, sizeof($$));
+ $$.a = $2;
+ $$.f = AF_INET6;
+ }
;
compare:
@@ -619,40 +1213,77 @@ range:
| ':' { $$ = FR_INCRANGE; }
;
+ipaddr: ipv4 { $$ = $1; }
+ | YY_IPV6 { $$.a = $1;
+ $$.f = AF_INET6;
+ }
+ ;
+
ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
yyerror("Invalid octet string for IP address");
return 0;
}
- $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
- $$.s_addr = htonl($$.s_addr);
+ bzero((char *)&$$, sizeof($$));
+ $$.a.in4.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
+ $$.a.in4.s_addr = htonl($$.a.in4.s_addr);
+ $$.f = AF_INET;
}
;
%%
+static wordtab_t proxies[] = {
+ { "dns", IPNY_DNS }
+};
+
+static wordtab_t dnswords[] = {
+ { "allow", IPNY_ALLOW },
+ { "block", IPNY_DENY },
+ { "deny", IPNY_DENY },
+ { "drop", IPNY_DENY },
+ { "pass", IPNY_ALLOW },
+
+};
+
static wordtab_t yywords[] = {
{ "age", IPNY_AGE },
{ "any", IPNY_ANY },
{ "auto", IPNY_AUTO },
{ "bimap", IPNY_BIMAP },
+ { "config", IPNY_CONFIG },
+ { "divert", IPNY_DIVERT },
+ { "dst", IPNY_DST },
+ { "dstlist", IPNY_DSTLIST },
{ "frag", IPNY_FRAG },
{ "from", IPNY_FROM },
+ { "hash", IPNY_HASH },
{ "icmpidmap", IPNY_ICMPIDMAP },
+ { "in", IPNY_IN },
+ { "inet", IPNY_INET },
+ { "inet6", IPNY_INET6 },
{ "mask", IPNY_MASK },
{ "map", IPNY_MAP },
{ "map-block", IPNY_MAPBLOCK },
{ "mssclamp", IPNY_MSSCLAMP },
{ "netmask", IPNY_MASK },
+ { "no", IPNY_NO },
+ { "on", IPNY_ON },
+ { "out", IPNY_OUT },
+ { "pool", IPNY_POOL },
{ "port", IPNY_PORT },
{ "portmap", IPNY_PORTMAP },
{ "ports", IPNY_PORTS },
+ { "proto", IPNY_PROTO },
{ "proxy", IPNY_PROXY },
+ { "purge", IPNY_PURGE },
{ "range", IPNY_RANGE },
+ { "rewrite", IPNY_REWRITE },
{ "rdr", IPNY_RDR },
{ "round-robin",IPNY_ROUNDROBIN },
{ "sequential", IPNY_SEQUENTIAL },
+ { "src", IPNY_SRC },
{ "sticky", IPNY_STICKY },
{ "tag", IPNY_TAG },
{ "tcp", IPNY_TCP },
@@ -671,15 +1302,19 @@ static wordtab_t yywords[] = {
};
-int ipnat_parsefile(fd, addfunc, ioctlfunc, filename)
-int fd;
-addfunc_t addfunc;
-ioctlfunc_t ioctlfunc;
-char *filename;
+int
+ipnat_parsefile(fd, addfunc, ioctlfunc, filename)
+ int fd;
+ addfunc_t addfunc;
+ ioctlfunc_t ioctlfunc;
+ char *filename;
{
FILE *fp = NULL;
+ int rval;
char *s;
+ yylineNum = 1;
+
(void) yysettab(yywords);
s = getenv("YYDEBUG");
@@ -691,45 +1326,49 @@ char *filename;
if (strcmp(filename, "-")) {
fp = fopen(filename, "r");
if (!fp) {
- fprintf(stderr, "fopen(%s) failed: %s\n", filename,
+ FPRINTF(stderr, "fopen(%s) failed: %s\n", filename,
STRERROR(errno));
return -1;
}
} else
fp = stdin;
- while (ipnat_parsesome(fd, addfunc, ioctlfunc, fp) == 1)
+ while ((rval = ipnat_parsesome(fd, addfunc, ioctlfunc, fp)) == 0)
;
if (fp != NULL)
fclose(fp);
- return 0;
+ if (rval == -1)
+ rval = 0;
+ else if (rval != 0)
+ rval = 1;
+ return rval;
}
-int ipnat_parsesome(fd, addfunc, ioctlfunc, fp)
-int fd;
-addfunc_t addfunc;
-ioctlfunc_t ioctlfunc;
-FILE *fp;
+int
+ipnat_parsesome(fd, addfunc, ioctlfunc, fp)
+ int fd;
+ addfunc_t addfunc;
+ ioctlfunc_t ioctlfunc;
+ FILE *fp;
{
char *s;
int i;
- yylineNum = 1;
-
natfd = fd;
+ parser_error = 0;
nataddfunc = addfunc;
natioctlfunc = ioctlfunc;
if (feof(fp))
- return 0;
+ return -1;
i = fgetc(fp);
if (i == EOF)
- return 0;
+ return -1;
if (ungetc(i, fp) == EOF)
- return 0;
+ return -1;
if (feof(fp))
- return 0;
+ return -1;
s = getenv("YYDEBUG");
if (s)
yydebug = atoi(s);
@@ -738,11 +1377,12 @@ FILE *fp;
yyin = fp;
yyparse();
- return 1;
+ return parser_error;
}
-static void newnatrule()
+static void
+newnatrule()
{
ipnat_t *n;
@@ -750,21 +1390,32 @@ static void newnatrule()
if (n == NULL)
return;
- if (nat == NULL)
+ if (nat == NULL) {
nattop = nat = n;
- else {
+ n->in_pnext = &nattop;
+ } else {
nat->in_next = n;
+ n->in_pnext = &nat->in_next;
nat = n;
}
+ n->in_flineno = yylineNum;
+ n->in_ifnames[0] = -1;
+ n->in_ifnames[1] = -1;
+ n->in_plabel = -1;
+ n->in_pconfig = -1;
+ n->in_size = sizeof(*n);
+
suggest_port = 0;
}
-static void setnatproto(p)
-int p;
+static void
+setnatproto(p)
+ int p;
{
- nat->in_p = p;
+ nat->in_pr[0] = p;
+ nat->in_pr[1] = p;
switch (p)
{
@@ -778,12 +1429,16 @@ int p;
break;
case IPPROTO_ICMP :
nat->in_flags &= ~IPN_TCPUDP;
- if (!(nat->in_flags & IPN_ICMPQUERY)) {
+ if (!(nat->in_flags & IPN_ICMPQUERY) &&
+ !(nat->in_redir & NAT_DIVERTUDP)) {
nat->in_dcmp = 0;
nat->in_scmp = 0;
- nat->in_pmin = 0;
- nat->in_pmax = 0;
- nat->in_pnext = 0;
+ nat->in_dpmin = 0;
+ nat->in_dpmax = 0;
+ nat->in_dpnext = 0;
+ nat->in_spmin = 0;
+ nat->in_spmax = 0;
+ nat->in_spnext = 0;
}
break;
default :
@@ -791,22 +1446,36 @@ int p;
nat->in_flags &= ~IPN_TCPUDP;
nat->in_dcmp = 0;
nat->in_scmp = 0;
- nat->in_pmin = 0;
- nat->in_pmax = 0;
- nat->in_pnext = 0;
+ nat->in_dpmin = 0;
+ nat->in_dpmax = 0;
+ nat->in_dpnext = 0;
+ nat->in_spmin = 0;
+ nat->in_spmax = 0;
+ nat->in_spnext = 0;
}
break;
}
+ if ((nat->in_flags & (IPN_TCP|IPN_UDP)) == 0) {
+ nat->in_stop = 0;
+ nat->in_dtop = 0;
+ nat->in_osport = 0;
+ nat->in_odport = 0;
+ nat->in_stop = 0;
+ nat->in_osport = 0;
+ nat->in_dtop = 0;
+ nat->in_odport = 0;
+ }
if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT)
nat->in_flags &= ~IPN_FIXEDDPORT;
}
-void ipnat_addrule(fd, ioctlfunc, ptr)
-int fd;
-ioctlfunc_t ioctlfunc;
-void *ptr;
+int
+ipnat_addrule(fd, ioctlfunc, ptr)
+ int fd;
+ ioctlfunc_t ioctlfunc;
+ void *ptr;
{
ioctlcmd_t add, del;
ipfobj_t obj;
@@ -815,20 +1484,19 @@ void *ptr;
ipn = ptr;
bzero((char *)&obj, sizeof(obj));
obj.ipfo_rev = IPFILTER_VERSION;
- obj.ipfo_size = sizeof(ipnat_t);
+ obj.ipfo_size = ipn->in_size;
obj.ipfo_type = IPFOBJ_IPNAT;
obj.ipfo_ptr = ptr;
- add = 0;
- del = 0;
if ((opts & OPT_DONOTHING) != 0)
fd = -1;
if (opts & OPT_ZERORULEST) {
add = SIOCZRLST;
- } else if (opts & OPT_INACTIVE) {
- add = SIOCADNAT;
- del = SIOCRMNAT;
+ del = 0;
+ } else if (opts & OPT_PURGE) {
+ add = 0;
+ del = SIOCPURGENAT;
} else {
add = SIOCADNAT;
del = SIOCRMNAT;
@@ -843,37 +1511,269 @@ void *ptr;
if ((opts & OPT_ZERORULEST) != 0) {
if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
if ((opts & OPT_DONOTHING) == 0) {
- fprintf(stderr, "%d:", yylineNum);
- perror("ioctl(SIOCZRLST)");
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(zero nat rule)",
+ ipn->in_flineno);
+ return ipf_perror_fd(fd, ioctlfunc, msg);
}
} else {
-#ifdef USE_QUAD_T
-/*
- printf("hits %qd bytes %qd ",
- (long long)fr->fr_hits,
- (long long)fr->fr_bytes);
-*/
+ PRINTF("hits %lu ", ipn->in_hits);
+#ifdef USE_QUAD_T
+ PRINTF("bytes %"PRIu64" ",
+ ipn->in_bytes[0] + ipn->in_bytes[1]);
#else
-/*
- printf("hits %ld bytes %ld ",
- fr->fr_hits, fr->fr_bytes);
-*/
+ PRINTF("bytes %lu ",
+ ipn->in_bytes[0] + ipn->in_bytes[1]);
#endif
printnat(ipn, opts);
}
} else if ((opts & OPT_REMOVE) != 0) {
if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) {
if ((opts & OPT_DONOTHING) == 0) {
- fprintf(stderr, "%d:", yylineNum);
- perror("ioctl(delete nat rule)");
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(delete nat rule)",
+ ipn->in_flineno);
+ return ipf_perror_fd(fd, ioctlfunc, msg);
}
}
} else {
if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) {
if ((opts & OPT_DONOTHING) == 0) {
- fprintf(stderr, "%d:", yylineNum);
- perror("ioctl(add/insert nat rule)");
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(add/insert nat rule)",
+ ipn->in_flineno);
+ if (errno == EEXIST) {
+ sprintf(msg + strlen(msg), "(line %d)",
+ ipn->in_flineno);
+ }
+ return ipf_perror_fd(fd, ioctlfunc, msg);
}
}
}
+ return 0;
+}
+
+
+static void
+setmapifnames()
+{
+ if (nat->in_ifnames[1] == -1)
+ nat->in_ifnames[1] = nat->in_ifnames[0];
+
+ if ((suggest_port == 1) && (nat->in_flags & IPN_TCPUDP) == 0)
+ nat->in_flags |= IPN_TCPUDP;
+
+ if ((nat->in_flags & IPN_TCPUDP) == 0)
+ setnatproto(nat->in_pr[1]);
+
+ if (((nat->in_redir & NAT_MAPBLK) != 0) ||
+ ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
+ nat_setgroupmap(nat);
+}
+
+
+static void
+setrdrifnames()
+{
+ if ((suggest_port == 1) && (nat->in_flags & IPN_TCPUDP) == 0)
+ nat->in_flags |= IPN_TCPUDP;
+
+ if ((nat->in_pr[0] == 0) && ((nat->in_flags & IPN_TCPUDP) == 0) &&
+ (nat->in_dpmin != 0 || nat->in_dpmax != 0 || nat->in_dpnext != 0))
+ setnatproto(IPPROTO_TCP);
+
+ if (nat->in_ifnames[1] == -1)
+ nat->in_ifnames[1] = nat->in_ifnames[0];
+}
+
+
+static void
+proxy_setconfig(proxy)
+ int proxy;
+{
+ if (proxy == IPNY_DNS) {
+ yysetfixeddict(dnswords);
+ }
+}
+
+
+static void
+proxy_unsetconfig()
+{
+ yyresetdict();
+}
+
+
+static namelist_t *
+proxy_dns_add_pass(prefix, name)
+ char *prefix, *name;
+{
+ namelist_t *n;
+
+ n = calloc(1, sizeof(*n));
+ if (n != NULL) {
+ if (prefix == NULL || *prefix == '\0') {
+ n->na_name = strdup(name);
+ } else {
+ n->na_name = malloc(strlen(name) + strlen(prefix) + 1);
+ strcpy(n->na_name, prefix);
+ strcat(n->na_name, name);
+ }
+ }
+ return n;
+}
+
+
+static namelist_t *
+proxy_dns_add_block(prefix, name)
+ char *prefix, *name;
+{
+ namelist_t *n;
+
+ n = calloc(1, sizeof(*n));
+ if (n != NULL) {
+ if (prefix == NULL || *prefix == '\0') {
+ n->na_name = strdup(name);
+ } else {
+ n->na_name = malloc(strlen(name) + strlen(prefix) + 1);
+ strcpy(n->na_name, prefix);
+ strcat(n->na_name, name);
+ }
+ n->na_value = 1;
+ }
+ return n;
+}
+
+
+static void
+proxy_addconfig(proxy, proto, conf, list)
+ char *proxy, *conf;
+ int proto;
+ namelist_t *list;
+{
+ proxyrule_t *pr;
+
+ pr = calloc(1, sizeof(*pr));
+ if (pr != NULL) {
+ pr->pr_proto = proto;
+ pr->pr_proxy = proxy;
+ pr->pr_conf = conf;
+ pr->pr_names = list;
+ pr->pr_next = prules;
+ prules = pr;
+ }
+}
+
+
+static void
+proxy_loadrules(fd, ioctlfunc, rules)
+ int fd;
+ ioctlfunc_t ioctlfunc;
+ proxyrule_t *rules;
+{
+ proxyrule_t *pr;
+
+ while ((pr = rules) != NULL) {
+ proxy_loadconfig(fd, ioctlfunc, pr->pr_proxy, pr->pr_proto,
+ pr->pr_conf, pr->pr_names);
+ rules = pr->pr_next;
+ free(pr->pr_conf);
+ free(pr);
+ }
+}
+
+
+static void
+proxy_loadconfig(fd, ioctlfunc, proxy, proto, conf, list)
+ int fd;
+ ioctlfunc_t ioctlfunc;
+ char *proxy, *conf;
+ int proto;
+ namelist_t *list;
+{
+ namelist_t *na;
+ ipfobj_t obj;
+ ap_ctl_t pcmd;
+
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_type = IPFOBJ_PROXYCTL;
+ obj.ipfo_size = sizeof(pcmd);
+ obj.ipfo_ptr = &pcmd;
+
+ while ((na = list) != NULL) {
+ if ((opts & OPT_REMOVE) != 0)
+ pcmd.apc_cmd = APC_CMD_DEL;
+ else
+ pcmd.apc_cmd = APC_CMD_ADD;
+ pcmd.apc_dsize = strlen(na->na_name) + 1;
+ pcmd.apc_data = na->na_name;
+ pcmd.apc_arg = na->na_value;
+ pcmd.apc_p = proto;
+
+ strncpy(pcmd.apc_label, proxy, APR_LABELLEN);
+ pcmd.apc_label[APR_LABELLEN - 1] = '\0';
+
+ strncpy(pcmd.apc_config, conf, APR_LABELLEN);
+ pcmd.apc_config[APR_LABELLEN - 1] = '\0';
+
+ if ((*ioctlfunc)(fd, SIOCPROXY, (void *)&obj) == -1) {
+ if ((opts & OPT_DONOTHING) == 0) {
+ char msg[80];
+
+ sprintf(msg, "%d:ioctl(add/remove proxy rule)",
+ yylineNum);
+ ipf_perror_fd(fd, ioctlfunc, msg);
+ return;
+ }
+ }
+
+ list = na->na_next;
+ free(na->na_name);
+ free(na);
+ }
+}
+
+
+static void
+setifname(np, idx, name)
+ ipnat_t **np;
+ int idx;
+ char *name;
+{
+ int pos;
+
+ pos = addname(np, name);
+ if (pos == -1)
+ return;
+ (*np)->in_ifnames[idx] = pos;
+}
+
+
+static int
+addname(np, name)
+ ipnat_t **np;
+ char *name;
+{
+ ipnat_t *n;
+ int nlen;
+ int pos;
+
+ nlen = strlen(name) + 1;
+ n = realloc(*np, (*np)->in_size + nlen);
+ if (*np == nattop)
+ nattop = n;
+ *np = n;
+ if (n == NULL)
+ return -1;
+ if (n->in_pnext != NULL)
+ *n->in_pnext = n;
+ n->in_size += nlen;
+ pos = n->in_namelen;
+ n->in_namelen += nlen;
+ strcpy(n->in_names + pos, name);
+ n->in_names[n->in_namelen] = '\0';
+ return pos;
}
diff --git a/contrib/ipfilter/tools/ippool.c b/contrib/ipfilter/tools/ippool.c
index 8b7096050736..49cf7dae63d7 100644
--- a/contrib/ipfilter/tools/ippool.c
+++ b/contrib/ipfilter/tools/ippool.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2002-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -61,41 +61,48 @@ int poolflush __P((int, char *[]));
int poolstats __P((int, char *[]));
int gettype __P((char *, u_int *));
int getrole __P((char *));
-int setnodeaddr __P((ip_pool_node_t *node, char *arg));
-void showpools_live __P((int, int, ip_pool_stat_t *, char *));
+int setnodeaddr __P((int, int, void *ptr, char *arg));
+void showpools_live __P((int, int, ipf_pool_stat_t *, char *));
void showhashs_live __P((int, int, iphtstat_t *, char *));
+void showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
int opts = 0;
int fd = -1;
int use_inet6 = 0;
+wordtab_t *pool_fields = NULL;
+int nohdrfields = 0;
-void usage(prog)
-char *prog;
+void
+usage(prog)
+ char *prog;
{
fprintf(stderr, "Usage:\t%s\n", prog);
- fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
- fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
- fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n");
- fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n");
- fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n");
- fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
- fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
- fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
+ fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
+ fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
+ fprintf(stderr, "\t-f <file> [-dnuv]\n");
+ fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
+ fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-O <fields>]\n");
+ fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
+ fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
+ fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
exit(1);
}
-int main(argc, argv)
-int argc;
-char *argv[];
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
{
- int err;
+ int err = 1;
if (argc < 2)
usage(argv[0]);
- switch (getopt(argc, argv, "aAf:FlrRs"))
+ assigndefined(getenv("IPPOOL_PREDEFINED"));
+
+ switch (getopt(argc, argv, "aAf:FlnrRsv"))
{
case 'a' :
err = poolnodecommand(0, argc, argv);
@@ -112,6 +119,9 @@ char *argv[];
case 'l' :
err = poollist(argc, argv);
break;
+ case 'n' :
+ opts |= OPT_DONOTHING|OPT_DONTOPEN;
+ break;
case 'r' :
err = poolnodecommand(1, argc, argv);
break;
@@ -121,6 +131,9 @@ char *argv[];
case 's' :
err = poolstats(argc, argv);
break;
+ case 'v' :
+ opts |= OPT_VERBOSE;
+ break;
default :
exit(1);
}
@@ -131,19 +144,23 @@ char *argv[];
}
-int poolnodecommand(remove, argc, argv)
-int remove, argc;
-char *argv[];
+int
+poolnodecommand(remove, argc, argv)
+ int remove, argc;
+ char *argv[];
{
- int err, c, ipset, role;
+ int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
char *poolname = NULL;
- ip_pool_node_t node;
+ ip_pool_node_t pnode;
+ iphtent_t hnode;
+ void *ptr = &pnode;
ipset = 0;
role = IPL_LOGIPF;
- bzero((char *)&node, sizeof(node));
+ bzero((char *)&pnode, sizeof(pnode));
+ bzero((char *)&hnode, sizeof(hnode));
- while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1)
+ while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1)
switch (c)
{
case 'd' :
@@ -151,16 +168,21 @@ char *argv[];
ippool_yydebug++;
break;
case 'i' :
- if (setnodeaddr(&node, optarg) == 0)
+ if (setnodeaddr(type, role, ptr, optarg) == 0)
ipset = 1;
break;
case 'm' :
poolname = optarg;
break;
case 'n' :
- opts |= OPT_DONOTHING;
+ opts |= OPT_DONOTHING|OPT_DONTOPEN;
break;
case 'o' :
+ if (ipset == 1) {
+ fprintf(stderr,
+ "cannot set role after ip address\n");
+ return -1;
+ }
role = getrole(optarg);
if (role == IPL_LOGNONE)
return -1;
@@ -168,13 +190,39 @@ char *argv[];
case 'R' :
opts |= OPT_NORESOLVE;
break;
+ case 't' :
+ if (ipset == 1) {
+ fprintf(stderr,
+ "cannot set type after ip address\n");
+ return -1;
+ }
+ type = gettype(optarg, NULL);
+ switch (type) {
+ case IPLT_NONE :
+ fprintf(stderr, "unknown type '%s'\n", optarg);
+ return -1;
+ case IPLT_HASH :
+ ptr = &hnode;
+ break;
+ case IPLT_POOL :
+ default :
+ break;
+ }
+ break;
+ case 'T' :
+ ttl = atoi(optarg);
+ if (ttl < 0) {
+ fprintf(stderr, "cannot set negative ttl\n");
+ return -1;
+ }
+ break;
case 'v' :
opts |= OPT_VERBOSE;
break;
}
if (argv[optind] != NULL && ipset == 0) {
- if (setnodeaddr(&node, argv[optind]) == 0)
+ if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
ipset = 1;
}
@@ -191,17 +239,30 @@ char *argv[];
return -1;
}
- if (remove == 0)
- err = load_poolnode(0, poolname, &node, ioctl);
- else
- err = remove_poolnode(0, poolname, &node, ioctl);
+ switch (type) {
+ case IPLT_POOL :
+ if (remove == 0)
+ err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
+ else
+ err = remove_poolnode(role, poolname, &pnode, ioctl);
+ break;
+ case IPLT_HASH :
+ if (remove == 0)
+ err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
+ else
+ err = remove_hashnode(role, poolname, &hnode, ioctl);
+ break;
+ default :
+ break;
+ }
return err;
}
-int poolcommand(remove, argc, argv)
-int remove, argc;
-char *argv[];
+int
+poolcommand(remove, argc, argv)
+ int remove, argc;
+ char *argv[];
{
int type, role, c, err;
char *poolname;
@@ -216,7 +277,7 @@ char *argv[];
bzero((char *)&iph, sizeof(iph));
bzero((char *)&pool, sizeof(pool));
- while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1)
+ while ((c = getopt(argc, argv, "dm:no:RSv")) != -1)
switch (c)
{
case 'd' :
@@ -227,7 +288,7 @@ char *argv[];
poolname = optarg;
break;
case 'n' :
- opts |= OPT_DONOTHING;
+ opts |= OPT_DONOTHING|OPT_DONTOPEN;
break;
case 'o' :
role = getrole(optarg);
@@ -242,13 +303,6 @@ char *argv[];
case 'S' :
iph.iph_seed = atoi(optarg);
break;
- case 't' :
- type = gettype(optarg, &iph.iph_type);
- if (type == IPLT_NONE) {
- fprintf(stderr, "unknown type '%s'\n", optarg);
- return -1;
- }
- break;
case 'v' :
opts |= OPT_VERBOSE;
break;
@@ -262,6 +316,12 @@ char *argv[];
return -1;
}
+ type = gettype(argv[optind], &iph.iph_type);
+ if (type == IPLT_NONE) {
+ fprintf(stderr, "unknown type '%s'\n", argv[optind]);
+ return -1;
+ }
+
if (type == IPLT_HASH) {
strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
@@ -297,9 +357,10 @@ char *argv[];
}
-int loadpoolfile(argc, argv, infile)
-int argc;
-char *argv[], *infile;
+int
+loadpoolfile(argc, argv, infile)
+ int argc;
+ char *argv[], *infile;
{
int c;
@@ -313,7 +374,7 @@ char *argv[], *infile;
ippool_yydebug++;
break;
case 'n' :
- opts |= OPT_DONOTHING;
+ opts |= OPT_DONOTHING|OPT_DONTOPEN;
break;
case 'R' :
opts |= OPT_NORESOLVE;
@@ -329,7 +390,7 @@ char *argv[], *infile;
if (opts & OPT_DEBUG)
fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
- if (!(opts & OPT_DONOTHING) && (fd == -1)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
fd = open(IPLOOKUP_NAME, O_RDWR);
if (fd == -1) {
perror("open(IPLOOKUP_NAME)");
@@ -343,12 +404,14 @@ char *argv[], *infile;
}
-int poolstats(argc, argv)
-int argc;
-char *argv[];
+int
+poolstats(argc, argv)
+ int argc;
+ char *argv[];
{
int c, type, role, live_kernel;
- ip_pool_stat_t plstat;
+ ipf_pool_stat_t plstat;
+ ipf_dstl_stat_t dlstat;
char *kernel, *core;
iphtstat_t htstat;
iplookupop_t op;
@@ -398,7 +461,7 @@ char *argv[];
if (opts & OPT_DEBUG)
fprintf(stderr, "poolstats: opts = %#x\n", opts);
- if (!(opts & OPT_DONOTHING) && (fd == -1)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
fd = open(IPLOOKUP_NAME, O_RDWR);
if (fd == -1) {
perror("open(IPLOOKUP_NAME)");
@@ -410,14 +473,14 @@ char *argv[];
op.iplo_type = IPLT_POOL;
op.iplo_struct = &plstat;
op.iplo_size = sizeof(plstat);
- if (!(opts & OPT_DONOTHING)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
- perror("ioctl(SIOCLOOKUPSTAT)");
+ ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
return -1;
}
- printf("Pools:\t%lu\n", plstat.ipls_pools);
- printf("Nodes:\t%lu\n", plstat.ipls_nodes);
+ printf("%lu\taddress pools\n", plstat.ipls_pools);
+ printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
}
}
@@ -425,24 +488,49 @@ char *argv[];
op.iplo_type = IPLT_HASH;
op.iplo_struct = &htstat;
op.iplo_size = sizeof(htstat);
- if (!(opts & OPT_DONOTHING)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
+ c = ioctl(fd, SIOCLOOKUPSTAT, &op);
+ if (c == -1) {
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
+ return -1;
+ }
+ printf("%lu\thash tables\n", htstat.iphs_numtables);
+ printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
+ printf("%lu\thash table no memory \n",
+ htstat.iphs_nomem);
+ }
+ }
+
+ if (type == IPLT_ALL || type == IPLT_DSTLIST) {
+ op.iplo_type = IPLT_DSTLIST;
+ op.iplo_struct = &dlstat;
+ op.iplo_size = sizeof(dlstat);
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
- perror("ioctl(SIOCLOOKUPSTAT)");
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
return -1;
}
- printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
- printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
- printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
+ printf("%u\tdestination lists\n",
+ dlstat.ipls_numlists);
+ printf("%u\tdestination list nodes\n",
+ dlstat.ipls_numnodes);
+ printf("%lu\tdestination list no memory\n",
+ dlstat.ipls_nomem);
+ printf("%u\tdestination list zombies\n",
+ dlstat.ipls_numdereflists);
+ printf("%u\tdesetination list node zombies\n",
+ dlstat.ipls_numderefnodes);
}
}
return 0;
}
-int poolflush(argc, argv)
-int argc;
-char *argv[];
+int
+poolflush(argc, argv)
+ int argc;
+ char *argv[];
{
int c, role, type, arg;
iplookupflush_t flush;
@@ -479,7 +567,7 @@ char *argv[];
if (opts & OPT_DEBUG)
fprintf(stderr, "poolflush: opts = %#x\n", opts);
- if (!(opts & OPT_DONOTHING) && (fd == -1)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
fd = open(IPLOOKUP_NAME, O_RDWR);
if (fd == -1) {
perror("open(IPLOOKUP_NAME)");
@@ -492,22 +580,23 @@ char *argv[];
flush.iplf_unit = role;
flush.iplf_arg = arg;
- if (!(opts & OPT_DONOTHING)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
- perror("ioctl(SIOCLOOKUPFLUSH)");
+ ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
exit(1);
}
}
- printf("%zd object%s flushed\n", flush.iplf_count,
+ printf("%u object%s flushed\n", flush.iplf_count,
(flush.iplf_count == 1) ? "" : "s");
return 0;
}
-int getrole(rolename)
-char *rolename;
+int
+getrole(rolename)
+ char *rolename;
{
int role;
@@ -537,19 +626,20 @@ char *rolename;
}
-int gettype(typename, minor)
-char *typename;
-u_int *minor;
+int
+gettype(typename, minor)
+ char *typename;
+ u_int *minor;
{
int type;
- if (!strcasecmp(optarg, "tree") || !strcasecmp(optarg, "pool")) {
+ if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
type = IPLT_POOL;
- } else if (!strcasecmp(optarg, "hash")) {
+ } else if (!strcasecmp(typename, "hash")) {
type = IPLT_HASH;
if (minor != NULL)
*minor = IPHASH_LOOKUP;
- } else if (!strcasecmp(optarg, "group-map")) {
+ } else if (!strcasecmp(typename, "group-map")) {
type = IPLT_HASH;
if (minor != NULL)
*minor = IPHASH_GROUPMAP;
@@ -560,9 +650,10 @@ u_int *minor;
}
-int poollist(argc, argv)
-int argc;
-char *argv[];
+int
+poollist(argc, argv)
+ int argc;
+ char *argv[];
{
char *kernel, *core, *poolname;
int c, role, type, live_kernel;
@@ -599,6 +690,9 @@ char *argv[];
return -1;
}
break;
+ case 'O' :
+ pool_fields = parsefields(poolfields, optarg);
+ break;
case 'R' :
opts |= OPT_NORESOLVE;
break;
@@ -617,7 +711,7 @@ char *argv[];
if (opts & OPT_DEBUG)
fprintf(stderr, "poollist: opts = %#x\n", opts);
- if (!(opts & OPT_DONOTHING) && (fd == -1)) {
+ if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
fd = open(IPLOOKUP_NAME, O_RDWR);
if (fd == -1) {
perror("open(IPLOOKUP_NAME)");
@@ -640,9 +734,10 @@ char *argv[];
}
-void poollist_dead(role, poolname, type, kernel, core)
-int role, type;
-char *poolname, *kernel, *core;
+void
+poollist_dead(role, poolname, type, kernel, core)
+ int role, type;
+ char *poolname, *kernel, *core;
{
iphtable_t *hptr;
ip_pool_t *ptr;
@@ -665,14 +760,15 @@ char *poolname, *kernel, *core;
ptr = pools[role];
while (ptr != NULL) {
ptr = printpool(ptr, kmemcpywrap, poolname,
- opts);
+ opts, pool_fields);
}
} else {
for (role = 0; role <= IPL_LOGMAX; role++) {
ptr = pools[role];
while (ptr != NULL) {
ptr = printpool(ptr, kmemcpywrap,
- poolname, opts);
+ poolname, opts,
+ pool_fields);
}
}
role = IPL_LOGALL;
@@ -693,14 +789,15 @@ char *poolname, *kernel, *core;
hptr = tables[role];
while (hptr != NULL) {
hptr = printhash(hptr, kmemcpywrap,
- poolname, opts);
+ poolname, opts, pool_fields);
}
} else {
for (role = 0; role <= IPL_LOGMAX; role++) {
hptr = tables[role];
while (hptr != NULL) {
hptr = printhash(hptr, kmemcpywrap,
- poolname, opts);
+ poolname, opts,
+ pool_fields);
}
}
}
@@ -708,12 +805,12 @@ char *poolname, *kernel, *core;
}
-void poollist_live(role, poolname, type, fd)
-int role, type, fd;
-char *poolname;
+void
+poollist_live(role, poolname, type, fd)
+ int role, type, fd;
+ char *poolname;
{
- ip_pool_stat_t plstat;
- iphtstat_t htstat;
+ ipf_pool_stat_t plstat;
iplookupop_t op;
int c;
@@ -729,18 +826,18 @@ char *poolname;
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
- perror("ioctl(SIOCLOOKUPSTAT)");
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
return;
}
showpools_live(fd, role, &plstat, poolname);
} else {
- for (role = 0; role <= IPL_LOGMAX; role++) {
+ for (role = -1; role <= IPL_LOGMAX; role++) {
op.iplo_unit = role;
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
- perror("ioctl(SIOCLOOKUPSTAT)");
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
return;
}
@@ -752,6 +849,8 @@ char *poolname;
}
if (type == IPLT_ALL || type == IPLT_HASH) {
+ iphtstat_t htstat;
+
op.iplo_type = IPLT_HASH;
op.iplo_size = sizeof(htstat);
op.iplo_struct = &htstat;
@@ -763,7 +862,7 @@ char *poolname;
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
- perror("ioctl(SIOCLOOKUPSTAT)");
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
return;
}
showhashs_live(fd, role, &htstat, poolname);
@@ -773,21 +872,57 @@ char *poolname;
op.iplo_unit = role;
c = ioctl(fd, SIOCLOOKUPSTAT, &op);
if (c == -1) {
- perror("ioctl(SIOCLOOKUPSTAT)");
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
return;
}
showhashs_live(fd, role, &htstat, poolname);
}
+ role = IPL_LOGALL;
+ }
+ }
+
+ if (type == IPLT_ALL || type == IPLT_DSTLIST) {
+ ipf_dstl_stat_t dlstat;
+
+ op.iplo_type = IPLT_DSTLIST;
+ op.iplo_size = sizeof(dlstat);
+ op.iplo_struct = &dlstat;
+ op.iplo_name[0] = '\0';
+ op.iplo_arg = 0;
+
+ if (role != IPL_LOGALL) {
+ op.iplo_unit = role;
+
+ c = ioctl(fd, SIOCLOOKUPSTAT, &op);
+ if (c == -1) {
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
+ return;
+ }
+ showdstls_live(fd, role, &dlstat, poolname);
+ } else {
+ for (role = 0; role <= IPL_LOGMAX; role++) {
+
+ op.iplo_unit = role;
+ c = ioctl(fd, SIOCLOOKUPSTAT, &op);
+ if (c == -1) {
+ ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
+ return;
+ }
+
+ showdstls_live(fd, role, &dlstat, poolname);
+ }
+ role = IPL_LOGALL;
}
}
}
-void showpools_live(fd, role, plstp, poolname)
-int fd, role;
-ip_pool_stat_t *plstp;
-char *poolname;
+void
+showpools_live(fd, role, plstp, poolname)
+ int fd, role;
+ ipf_pool_stat_t *plstp;
+ char *poolname;
{
ipflookupiter_t iter;
ip_pool_t pool;
@@ -806,22 +941,27 @@ char *poolname;
iter.ili_unit = role;
*iter.ili_name = '\0';
- while (plstp->ipls_list[role] != NULL) {
+ bzero((char *)&pool, sizeof(pool));
+
+ while (plstp->ipls_list[role + 1] != NULL) {
if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
- perror("ioctl(SIOCLOOKUPITER)");
+ ipferror(fd, "ioctl(SIOCLOOKUPITER)");
break;
}
- printpool_live(&pool, fd, poolname, opts);
+ if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
+ ((opts & OPT_DEBUG) != 0))
+ printpool_live(&pool, fd, poolname, opts, pool_fields);
- plstp->ipls_list[role] = pool.ipo_next;
+ plstp->ipls_list[role + 1] = pool.ipo_next;
}
}
-void showhashs_live(fd, role, htstp, poolname)
-int fd, role;
-iphtstat_t *htstp;
-char *poolname;
+void
+showhashs_live(fd, role, htstp, poolname)
+ int fd, role;
+ iphtstat_t *htstp;
+ char *poolname;
{
ipflookupiter_t iter;
iphtable_t table;
@@ -842,18 +982,55 @@ char *poolname;
while (htstp->iphs_tables != NULL) {
if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
- perror("ioctl(SIOCLOOKUPITER)");
+ ipferror(fd, "ioctl(SIOCLOOKUPITER)");
break;
}
- printhash_live(&table, fd, poolname, opts);
+ printhash_live(&table, fd, poolname, opts, pool_fields);
htstp->iphs_tables = table.iph_next;
}
}
-int setnodeaddr(ip_pool_node_t *node, char *arg)
+void
+showdstls_live(fd, role, dlstp, poolname)
+ int fd, role;
+ ipf_dstl_stat_t *dlstp;
+ char *poolname;
+{
+ ipflookupiter_t iter;
+ ippool_dst_t table;
+ ipfobj_t obj;
+
+ obj.ipfo_rev = IPFILTER_VERSION;
+ obj.ipfo_type = IPFOBJ_LOOKUPITER;
+ obj.ipfo_size = sizeof(iter);
+ obj.ipfo_ptr = &iter;
+
+ iter.ili_type = IPLT_DSTLIST;
+ iter.ili_otype = IPFLOOKUPITER_LIST;
+ iter.ili_ival = IPFGENITER_LOOKUP;
+ iter.ili_nitems = 1;
+ iter.ili_data = &table;
+ iter.ili_unit = role;
+ *iter.ili_name = '\0';
+
+ while (dlstp->ipls_list[role] != NULL) {
+ if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
+ ipferror(fd, "ioctl(SIOCLOOKUPITER)");
+ break;
+ }
+
+ printdstl_live(&table, fd, poolname, opts, pool_fields);
+
+ dlstp->ipls_list[role] = table.ipld_next;
+ }
+}
+
+
+int
+setnodeaddr(int type, int role, void *ptr, char *arg)
{
struct in_addr mask;
char *s;
@@ -862,17 +1039,38 @@ int setnodeaddr(ip_pool_node_t *node, char *arg)
if (s == NULL)
mask.s_addr = 0xffffffff;
else if (strchr(s, '.') == NULL) {
- if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
+ if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
return -1;
} else {
mask.s_addr = inet_addr(s + 1);
}
if (s != NULL)
*s = '\0';
- node->ipn_addr.adf_len = sizeof(node->ipn_addr);
- node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
- node->ipn_mask.adf_len = sizeof(node->ipn_mask);
- node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
+
+ if (type == IPLT_POOL) {
+ ip_pool_node_t *node = ptr;
+
+ if (node->ipn_addr.adf_family == AF_INET)
+ node->ipn_addr.adf_len = offsetof(addrfamily_t,
+ adf_addr) +
+ sizeof(struct in_addr);
+#ifdef USE_INET6
+ else
+ node->ipn_addr.adf_len = offsetof(addrfamily_t,
+ adf_addr) +
+ sizeof(struct in6_addr);
+#endif
+ node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
+ node->ipn_mask.adf_len = node->ipn_addr.adf_len;
+ node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
+ } else if (type == IPLT_HASH) {
+ iphtent_t *node = ptr;
+
+ node->ipe_addr.in4.s_addr = inet_addr(arg);
+ node->ipe_mask.in4.s_addr = mask.s_addr;
+ node->ipe_family = AF_INET;
+ node->ipe_unit = role;
+ }
return 0;
}
diff --git a/contrib/ipfilter/tools/ippool_y.y b/contrib/ipfilter/tools/ippool_y.y
index 24f683bd1c19..34987452c65b 100644
--- a/contrib/ipfilter/tools/ippool_y.y
+++ b/contrib/ipfilter/tools/ippool_y.y
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -35,6 +35,7 @@
#include "netinet/ip_lookup.h"
#include "netinet/ip_pool.h"
#include "netinet/ip_htable.h"
+#include "netinet/ip_dstlist.h"
#include "ippool_l.h"
#include "kmem.h"
@@ -48,43 +49,52 @@ extern FILE *yyin;
static iphtable_t ipht;
static iphtent_t iphte;
static ip_pool_t iplo;
+static ippool_dst_t ipld;
static ioctlfunc_t poolioctl = NULL;
static char poolname[FR_GROUPLEN];
static iphtent_t *add_htablehosts __P((char *));
static ip_pool_node_t *add_poolhosts __P((char *));
+static ip_pool_node_t *read_whoisfile __P((char *));
+static void setadflen __P((addrfamily_t *));
%}
%union {
char *str;
u_32_t num;
- struct in_addr addr;
+ struct in_addr ip4;
struct alist_s *alist;
- struct in_addr adrmsk[2];
+ addrfamily_t adrmsk[2];
iphtent_t *ipe;
ip_pool_node_t *ipp;
- union i6addr ip6;
+ ipf_dstnode_t *ipd;
+ addrfamily_t ipa;
+ i6addr_t ip6;
}
-%token <num> YY_NUMBER YY_HEX
-%token <str> YY_STR
-%token YY_COMMENT
-%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
-%token YY_RANGE_OUT YY_RANGE_IN
-%token <ip6> YY_IPV6
-
-%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT
-%token IPT_TABLE IPT_GROUPMAP IPT_HASH
+%token <num> YY_NUMBER YY_HEX
+%token <str> YY_STR
+%token <ip6> YY_IPV6
+%token YY_COMMENT
+%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
+%token YY_RANGE_OUT YY_RANGE_IN
+%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL
+%token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH
%token IPT_ROLE IPT_TYPE IPT_TREE
-%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME
-%type <num> role table inout
+%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY
+%token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN
+%token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION
+%token IPT_WHOIS IPT_FILE
+%type <num> role table inout unit dstopts weighting
%type <ipp> ipftree range addrlist
%type <adrmsk> addrmask
%type <ipe> ipfgroup ipfhash hashlist hashentry
%type <ipe> groupentry setgrouplist grouplist
-%type <addr> ipaddr mask ipv4
-%type <str> number setgroup
+%type <ipa> ipaddr mask
+%type <ip4> ipv4
+%type <str> number setgroup name
+%type <ipd> dstentry dstentries dstlist
%%
file: line
@@ -93,25 +103,44 @@ file: line
| file assign
;
-line: table role ipftree eol { iplo.ipo_unit = $2;
+line: table role ipftree eol { ip_pool_node_t *n;
+ iplo.ipo_unit = $2;
iplo.ipo_list = $3;
load_pool(&iplo, poolioctl);
+ while ((n = $3) != NULL) {
+ $3 = n->ipn_next;
+ free(n);
+ }
resetlexer();
+ use_inet6 = 0;
}
- | table role ipfhash eol { ipht.iph_unit = $2;
+ | table role ipfhash eol { iphtent_t *h;
+ ipht.iph_unit = $2;
ipht.iph_type = IPHASH_LOOKUP;
load_hash(&ipht, $3, poolioctl);
+ while ((h = $3) != NULL) {
+ $3 = h->ipe_next;
+ free(h);
+ }
resetlexer();
+ use_inet6 = 0;
}
| groupmap role number ipfgroup eol
- { ipht.iph_unit = $2;
+ { iphtent_t *h;
+ ipht.iph_unit = $2;
strncpy(ipht.iph_name, $3,
sizeof(ipht.iph_name));
ipht.iph_type = IPHASH_GROUPMAP;
load_hash(&ipht, $4, poolioctl);
+ while ((h = $4) != NULL) {
+ $4 = h->ipe_next;
+ free(h);
+ }
resetlexer();
+ use_inet6 = 0;
}
| YY_COMMENT
+ | poolline eol
;
eol: ';'
@@ -132,6 +161,7 @@ assigning:
table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht));
bzero((char *)&iphte, sizeof(iphte));
bzero((char *)&iplo, sizeof(iplo));
+ bzero((char *)&ipld, sizeof(ipld));
*ipht.iph_name = '\0';
iplo.ipo_flags = IPHASH_ANON;
iplo.ipo_name[0] = '\0';
@@ -150,11 +180,15 @@ groupmap:
inout: IPT_IN { $$ = FR_INQUE; }
| IPT_OUT { $$ = FR_OUTQUE; }
;
-role:
- IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; }
- | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; }
- | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; }
- | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; }
+
+role: IPT_ROLE '=' unit { $$ = $3; }
+ ;
+
+unit: IPT_IPF { $$ = IPL_LOGIPF; }
+ | IPT_NAT { $$ = IPL_LOGNAT; }
+ | IPT_AUTH { $$ = IPL_LOGAUTH; }
+ | IPT_COUNT { $$ = IPL_LOGCOUNT; }
+ | IPT_ALL { $$ = IPL_LOGALL; }
;
ipftree:
@@ -183,14 +217,21 @@ ipfgroup:
$1,
FR_GROUPLEN);
$$ = $4;
+ free($1);
}
- | hashopts start setgrouplist end { $$ = $3; }
+ | hashopts start setgrouplist end
+ { $$ = $3; }
;
number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3);
$$ = poolname;
}
- | IPT_NAME '=' YY_STR { $$ = $3; }
+ | IPT_NAME '=' YY_STR { strncpy(poolname, $3,
+ FR_GROUPLEN);
+ poolname[FR_GROUPLEN-1]='\0';
+ free($3);
+ $$ = poolname;
+ }
| { $$ = ""; }
;
@@ -198,6 +239,7 @@ setgroup:
IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1];
strncpy(tmp, $3, FR_GROUPLEN);
$$ = strdup(tmp);
+ free($3);
}
| IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1];
sprintf(tmp, "%u", $3);
@@ -212,119 +254,162 @@ hashopts:
;
addrlist:
- next { $$ = NULL; }
- | range next addrlist { $1->ipn_next = $3; $$ = $1; }
+ ';' { $$ = NULL; }
+ | range next addrlist { $$ = $1;
+ while ($1->ipn_next != NULL)
+ $1 = $1->ipn_next;
+ $1->ipn_next = $3;
+ }
| range next { $$ = $1; }
;
grouplist:
- next { $$ = NULL; }
+ ';' { $$ = NULL; }
| groupentry next grouplist { $$ = $1; $1->ipe_next = $3; }
| addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t));
- bcopy((char *)&($1[0]),
- (char *)&($$->ipe_addr),
- sizeof($$->ipe_addr));
- bcopy((char *)&($1[1]),
- (char *)&($$->ipe_mask),
- sizeof($$->ipe_mask));
+ $$->ipe_addr = $1[0].adf_addr;
+ $$->ipe_mask = $1[1].adf_addr;
+ $$->ipe_family = $1[0].adf_family;
$$->ipe_next = $3;
}
| groupentry next { $$ = $1; }
| addrmask next { $$ = calloc(1, sizeof(iphtent_t));
- bcopy((char *)&($1[0]),
- (char *)&($$->ipe_addr),
- sizeof($$->ipe_addr));
- bcopy((char *)&($1[1]),
- (char *)&($$->ipe_mask),
- sizeof($$->ipe_mask));
+ $$->ipe_addr = $1[0].adf_addr;
+ $$->ipe_mask = $1[1].adf_addr;
+#ifdef AF_INET6
+ if (use_inet6)
+ $$->ipe_family = AF_INET6;
+ else
+#endif
+ $$->ipe_family = AF_INET;
+ }
+ | YY_STR { $$ = add_htablehosts($1);
+ free($1);
}
;
setgrouplist:
- next { $$ = NULL; }
+ ';' { $$ = NULL; }
| groupentry next { $$ = $1; }
| groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; }
;
groupentry:
addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t));
- bcopy((char *)&($1[0]),
- (char *)&($$->ipe_addr),
- sizeof($$->ipe_addr));
- bcopy((char *)&($1[1]),
- (char *)&($$->ipe_mask),
- sizeof($$->ipe_mask));
+ $$->ipe_addr = $1[0].adf_addr;
+ $$->ipe_mask = $1[1].adf_addr;
strncpy($$->ipe_group, $3,
FR_GROUPLEN);
+#ifdef AF_INET6
+ if (use_inet6)
+ $$->ipe_family = AF_INET6;
+ else
+#endif
+ $$->ipe_family = AF_INET;
free($3);
}
- | YY_STR { $$ = add_htablehosts($1); }
;
-range: addrmask { $$ = calloc(1, sizeof(*$$));
- $$->ipn_info = 0;
- $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
- $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr;
- $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
- $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr;
- }
- | '!' addrmask { $$ = calloc(1, sizeof(*$$));
- $$->ipn_info = 1;
- $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
- $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr;
- $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
- $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr;
- }
- | YY_STR { $$ = add_poolhosts($1); }
+range: addrmask { $$ = calloc(1, sizeof(*$$));
+ $$->ipn_info = 0;
+ $$->ipn_addr = $1[0];
+ $$->ipn_mask = $1[1];
+ }
+ | '!' addrmask { $$ = calloc(1, sizeof(*$$));
+ $$->ipn_info = 1;
+ $$->ipn_addr = $2[0];
+ $$->ipn_mask = $2[1];
+ }
+ | YY_STR { $$ = add_poolhosts($1);
+ free($1);
+ }
+ | IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3);
+ free($3);
+ }
+ ;
hashlist:
- next { $$ = NULL; }
+ ';' { $$ = NULL; }
| hashentry next { $$ = $1; }
| hashentry next hashlist { $1->ipe_next = $3; $$ = $1; }
;
hashentry:
- addrmask { $$ = calloc(1, sizeof(iphtent_t));
- bcopy((char *)&($1[0]),
- (char *)&($$->ipe_addr),
- sizeof($$->ipe_addr));
- bcopy((char *)&($1[1]),
- (char *)&($$->ipe_mask),
- sizeof($$->ipe_mask));
- }
- | YY_STR { $$ = add_htablehosts($1); }
+ addrmask { $$ = calloc(1, sizeof(iphtent_t));
+ $$->ipe_addr = $1[0].adf_addr;
+ $$->ipe_mask = $1[1].adf_addr;
+#ifdef USE_INET6
+ if (use_inet6)
+ $$->ipe_family = AF_INET6;
+ else
+#endif
+ $$->ipe_family = AF_INET;
+ }
+ | YY_STR { $$ = add_htablehosts($1);
+ free($1);
+ }
;
addrmask:
- ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr;
- yyexpectaddr = 0;
+ ipaddr '/' mask { $$[0] = $1;
+ setadflen(&$$[0]);
+ $$[1] = $3;
+ $$[1].adf_len = $$[0].adf_len;
}
- | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff;
- yyexpectaddr = 0;
+ | ipaddr { $$[0] = $1;
+ setadflen(&$$[1]);
+ $$[1].adf_len = $$[0].adf_len;
+#ifdef USE_INET6
+ if (use_inet6)
+ memset(&$$[1].adf_addr, 0xff,
+ sizeof($$[1].adf_addr.in6));
+ else
+#endif
+ memset(&$$[1].adf_addr, 0xff,
+ sizeof($$[1].adf_addr.in4));
}
;
-ipaddr: ipv4 { $$ = $1; }
- | YY_NUMBER { $$.s_addr = htonl($1); }
- ;
-
-mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); }
- | ipv4 { $$ = $1; }
- ;
-
-start: '{' { yyexpectaddr = 1; }
- ;
-
-end: '}' { yyexpectaddr = 0; }
+ipaddr: ipv4 { $$.adf_addr.in4 = $1;
+ $$.adf_family = AF_INET;
+ setadflen(&$$);
+ use_inet6 = 0;
+ }
+ | YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1);
+ $$.adf_family = AF_INET;
+ setadflen(&$$);
+ use_inet6 = 0;
+ }
+ | YY_IPV6 { $$.adf_addr = $1;
+ $$.adf_family = AF_INET6;
+ setadflen(&$$);
+ use_inet6 = 1;
+ }
;
-next: ';' { yyexpectaddr = 1; }
+mask: YY_NUMBER { bzero(&$$, sizeof($$));
+ if (use_inet6) {
+ if (ntomask(AF_INET6, $1,
+ (u_32_t *)&$$.adf_addr) == -1)
+ yyerror("bad bitmask");
+ } else {
+ if (ntomask(AF_INET, $1,
+ (u_32_t *)&$$.adf_addr.in4) == -1)
+ yyerror("bad bitmask");
+ }
+ }
+ | ipv4 { bzero(&$$, sizeof($$));
+ $$.adf_addr.in4 = $1;
+ }
+ | YY_IPV6 { bzero(&$$, sizeof($$));
+ $$.adf_addr = $1;
+ }
;
-size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; }
+size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; }
;
-seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; }
+seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; }
;
ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
@@ -336,26 +421,180 @@ ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
$$.s_addr = htonl($$.s_addr);
}
;
+
+next: ';' { yyexpectaddr = 1; }
+ ;
+
+start: '{' { yyexpectaddr = 1; }
+ ;
+
+end: '}' { yyexpectaddr = 0; }
+ ;
+
+poolline:
+ IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')'
+ start dstlist end
+ { bzero((char *)&ipld, sizeof(ipld));
+ strncpy(ipld.ipld_name, $6,
+ sizeof(ipld.ipld_name));
+ ipld.ipld_unit = $2;
+ ipld.ipld_policy = $8;
+ load_dstlist(&ipld, poolioctl, $11);
+ resetlexer();
+ use_inet6 = 0;
+ free($6);
+ }
+ | IPT_POOL unit '/' IPT_TREE '(' name ';' ')'
+ start addrlist end
+ { bzero((char *)&iplo, sizeof(iplo));
+ strncpy(iplo.ipo_name, $6,
+ sizeof(iplo.ipo_name));
+ iplo.ipo_list = $10;
+ iplo.ipo_unit = $2;
+ load_pool(&iplo, poolioctl);
+ resetlexer();
+ use_inet6 = 0;
+ free($6);
+ }
+ | IPT_POOL '(' name ';' ')' start addrlist end
+ { bzero((char *)&iplo, sizeof(iplo));
+ strncpy(iplo.ipo_name, $3,
+ sizeof(iplo.ipo_name));
+ iplo.ipo_list = $7;
+ iplo.ipo_unit = IPL_LOGALL;
+ load_pool(&iplo, poolioctl);
+ resetlexer();
+ use_inet6 = 0;
+ free($3);
+ }
+ | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')'
+ start hashlist end
+ { iphtent_t *h;
+ bzero((char *)&ipht, sizeof(ipht));
+ strncpy(ipht.iph_name, $6,
+ sizeof(ipht.iph_name));
+ ipht.iph_unit = $2;
+ load_hash(&ipht, $11, poolioctl);
+ while ((h = ipht.iph_list) != NULL) {
+ ipht.iph_list = h->ipe_next;
+ free(h);
+ }
+ resetlexer();
+ use_inet6 = 0;
+ free($6);
+ }
+ | IPT_GROUPMAP '(' name ';' inout ';' ')'
+ start setgrouplist end
+ { iphtent_t *h;
+ bzero((char *)&ipht, sizeof(ipht));
+ strncpy(ipht.iph_name, $3,
+ sizeof(ipht.iph_name));
+ ipht.iph_type = IPHASH_GROUPMAP;
+ ipht.iph_unit = IPL_LOGIPF;
+ ipht.iph_flags = $5;
+ load_hash(&ipht, $9, poolioctl);
+ while ((h = ipht.iph_list) != NULL) {
+ ipht.iph_list = h->ipe_next;
+ free(h);
+ }
+ resetlexer();
+ use_inet6 = 0;
+ free($3);
+ }
+ ;
+
+name: IPT_NAME YY_STR { $$ = $2; }
+ | IPT_NUM YY_NUMBER { char name[80];
+ sprintf(name, "%d", $2);
+ $$ = strdup(name);
+ }
+ ;
+
+hashoptlist:
+ | hashopt ';'
+ | hashoptlist ';' hashopt ';'
+ ;
+hashopt:
+ IPT_SIZE YY_NUMBER
+ | IPT_SEED YY_NUMBER
+ ;
+
+dstlist:
+ dstentries { $$ = $1; }
+ | ';' { $$ = NULL; }
+ ;
+
+dstentries:
+ dstentry next { $$ = $1; }
+ | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; }
+ ;
+
+dstentry:
+ YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1;
+ $$ = calloc(1, size);
+ if ($$ != NULL) {
+ $$->ipfd_dest.fd_name = strlen($1) + 1;
+ bcopy($1, $$->ipfd_names,
+ $$->ipfd_dest.fd_name);
+ $$->ipfd_dest.fd_addr = $3;
+ $$->ipfd_size = size;
+ }
+ free($1);
+ }
+ | ipaddr { $$ = calloc(1, sizeof(*$$));
+ if ($$ != NULL) {
+ $$->ipfd_dest.fd_name = -1;
+ $$->ipfd_dest.fd_addr = $1;
+ $$->ipfd_size = sizeof(*$$);
+ }
+ }
+ ;
+
+dstopts:
+ { $$ = IPLDP_NONE; }
+ | IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; }
+ | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; }
+ | IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; }
+ | IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; }
+ | IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; }
+ | IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; }
+ ;
+
+weighting:
+ IPT_CONNECTION { $$ = IPLDP_CONNECTION; }
+ ;
%%
static wordtab_t yywords[] = {
- { "auth", IPT_AUTH },
- { "count", IPT_COUNT },
- { "group", IPT_GROUP },
- { "group-map", IPT_GROUPMAP },
- { "hash", IPT_HASH },
- { "in", IPT_IN },
- { "ipf", IPT_IPF },
- { "name", IPT_NAME },
- { "nat", IPT_NAT },
- { "number", IPT_NUM },
- { "out", IPT_OUT },
- { "role", IPT_ROLE },
- { "seed", IPT_SEED },
- { "size", IPT_SIZE },
- { "table", IPT_TABLE },
- { "tree", IPT_TREE },
- { "type", IPT_TYPE },
- { NULL, 0 }
+ { "all", IPT_ALL },
+ { "auth", IPT_AUTH },
+ { "connection", IPT_CONNECTION },
+ { "count", IPT_COUNT },
+ { "dst-hash", IPT_DSTHASH },
+ { "dstlist", IPT_DSTLIST },
+ { "file", IPT_FILE },
+ { "group", IPT_GROUP },
+ { "group-map", IPT_GROUPMAP },
+ { "hash", IPT_HASH },
+ { "in", IPT_IN },
+ { "ipf", IPT_IPF },
+ { "name", IPT_NAME },
+ { "nat", IPT_NAT },
+ { "number", IPT_NUM },
+ { "out", IPT_OUT },
+ { "policy", IPT_POLICY },
+ { "pool", IPT_POOL },
+ { "random", IPT_RANDOM },
+ { "round-robin", IPT_ROUNDROBIN },
+ { "role", IPT_ROLE },
+ { "seed", IPT_SEED },
+ { "size", IPT_SIZE },
+ { "src-hash", IPT_SRCHASH },
+ { "table", IPT_TABLE },
+ { "tree", IPT_TREE },
+ { "type", IPT_TYPE },
+ { "weighted", IPT_WEIGHTED },
+ { "whois", IPT_WHOIS },
+ { NULL, 0 }
};
@@ -441,8 +680,9 @@ char *url;
if (hlist == NULL)
return NULL;
- if (gethost(url, &hlist->al_addr) == -1)
+ if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
yyerror("Unknown hostname");
+ }
}
hbot = NULL;
@@ -453,10 +693,9 @@ char *url;
if (h == NULL)
break;
- bcopy((char *)&a->al_addr, (char *)&h->ipe_addr,
- sizeof(h->ipe_addr));
- bcopy((char *)&a->al_mask, (char *)&h->ipe_mask,
- sizeof(h->ipe_mask));
+ h->ipe_family = a->al_family;
+ h->ipe_addr = a->al_i6addr;
+ h->ipe_mask = a->al_i6mask;
if (hbot != NULL)
hbot->ipe_next = h;
@@ -487,8 +726,9 @@ char *url;
if (hlist == NULL)
return NULL;
- if (gethost(url, &hlist->al_addr) == -1)
+ if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
yyerror("Unknown hostname");
+ }
}
pbot = NULL;
@@ -498,16 +738,19 @@ char *url;
p = calloc(1, sizeof(*p));
if (p == NULL)
break;
+ p->ipn_mask.adf_addr = a->al_i6mask;
- p->ipn_addr.adf_len = 8;
- p->ipn_mask.adf_len = 8;
-
+ if (a->al_family == AF_INET) {
+ p->ipn_addr.adf_family = AF_INET;
+#ifdef USE_INET6
+ } else if (a->al_family == AF_INET6) {
+ p->ipn_addr.adf_family = AF_INET6;
+#endif
+ }
+ setadflen(&p->ipn_addr);
+ p->ipn_addr.adf_addr = a->al_i6addr;
p->ipn_info = a->al_not;
-
- bcopy((char *)&a->al_addr, (char *)&p->ipn_addr.adf_addr,
- sizeof(p->ipn_addr.adf_addr));
- bcopy((char *)&a->al_mask, (char *)&p->ipn_mask.adf_addr,
- sizeof(p->ipn_mask.adf_addr));
+ p->ipn_mask.adf_len = p->ipn_addr.adf_len;
if (pbot != NULL)
pbot->ipn_next = p;
@@ -520,3 +763,59 @@ char *url;
return ptop;
}
+
+
+ip_pool_node_t *
+read_whoisfile(file)
+ char *file;
+{
+ ip_pool_node_t *ntop, *ipn, node, *last;
+ char line[1024];
+ FILE *fp;
+
+ fp = fopen(file, "r");
+ if (fp == NULL)
+ return NULL;
+
+ last = NULL;
+ ntop = NULL;
+ while (fgets(line, sizeof(line) - 1, fp) != NULL) {
+ line[sizeof(line) - 1] = '\0';
+
+ if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask))
+ continue;
+ ipn = calloc(1, sizeof(*ipn));
+ if (ipn == NULL)
+ continue;
+ ipn->ipn_addr = node.ipn_addr;
+ ipn->ipn_mask = node.ipn_mask;
+ if (last == NULL)
+ ntop = ipn;
+ else
+ last->ipn_next = ipn;
+ last = ipn;
+ }
+ fclose(fp);
+ return ntop;
+}
+
+
+static void
+setadflen(afp)
+ addrfamily_t *afp;
+{
+ afp->adf_len = offsetof(addrfamily_t, adf_addr);
+ switch (afp->adf_family)
+ {
+ case AF_INET :
+ afp->adf_len += sizeof(struct in_addr);
+ break;
+#ifdef USE_INET6
+ case AF_INET6 :
+ afp->adf_len += sizeof(struct in6_addr);
+ break;
+#endif
+ default :
+ break;
+ }
+}
diff --git a/contrib/ipfilter/tools/ipscan_y.y b/contrib/ipfilter/tools/ipscan_y.y
index 5dbefd6ab5ae..d323f054bd27 100644
--- a/contrib/ipfilter/tools/ipscan_y.y
+++ b/contrib/ipfilter/tools/ipscan_y.y
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2004 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -13,6 +13,7 @@
#include "kmem.h"
#include "ipscan_l.h"
#include "netinet/ip_scan.h"
+#include <ctype.h>
#define YYDEBUG 1
@@ -60,7 +61,7 @@ int fd = -1;
%token <num> YY_NUMBER YY_HEX
%token <str> YY_STR
-%token YY_COMMENT
+%token YY_COMMENT
%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
%token YY_RANGE_OUT YY_RANGE_IN
%token <ip6> YY_IPV6
diff --git a/contrib/ipfilter/tools/ipsyncm.c b/contrib/ipfilter/tools/ipsyncm.c
index 600d39ad0d6c..41513fae3bcc 100644
--- a/contrib/ipfilter/tools/ipsyncm.c
+++ b/contrib/ipfilter/tools/ipsyncm.c
@@ -1,13 +1,13 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipsyncm.c,v 1.4.2.5 2006/08/26 11:21:14 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
#include <sys/types.h>
#include <sys/time.h>
@@ -49,13 +49,13 @@ static void handleterm(int sig)
}
#endif
-
+
/* should be large enough to hold header + any datatype */
#define BUFFERLEN 1400
int main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
struct sockaddr_in sin;
char buff[BUFFERLEN];
@@ -66,14 +66,14 @@ char *argv[];
u_32_t magic;
synchdr_t *sh;
char *progname;
-
+
progname = strrchr(argv[0], '/');
if (progname) {
progname++;
} else {
progname = argv[0];
}
-
+
if (argc < 2) {
usage(progname);
@@ -108,13 +108,13 @@ char *argv[];
syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME);
goto tryagain;
}
-
+
nfd = socket(AF_INET, SOCK_DGRAM, 0);
if (nfd == -1) {
syslog(LOG_ERR, "Socket :%m");
goto tryagain;
}
-
+
if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
syslog(LOG_ERR, "Connect: %m");
goto tryagain;
@@ -122,15 +122,15 @@ char *argv[];
syslog(LOG_INFO, "Sending data to %s",
inet_ntoa(sin.sin_addr));
-
- inbuf = 0;
+
+ inbuf = 0;
while (1) {
n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf);
-
+
printf("header : %d bytes read (header = %d bytes)\n",
- n1, sizeof(*sh));
-
+ n1, (int) sizeof(*sh));
+
if (n1 < 0) {
syslog(LOG_ERR, "Read error (header): %m");
goto tryagain;
@@ -143,8 +143,8 @@ char *argv[];
sleep(1);
continue;
}
-
- inbuf += n1;
+
+ inbuf += n1;
moreinbuf:
if (inbuf < sizeof(*sh)) {
@@ -153,7 +153,7 @@ moreinbuf:
sh = (synchdr_t *)buff;
len = ntohl(sh->sm_len);
- magic = ntohl(sh->sm_magic);
+ magic = ntohl(sh->sm_magic);
if (magic != SYNHDRMAGIC) {
syslog(LOG_ERR,
@@ -181,8 +181,8 @@ moreinbuf:
printf(" table:Unknown(%d)", sh->sm_table);
printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num));
-#endif
-
+#endif
+
if (inbuf < sizeof(*sh) + len) {
continue; /* need more data */
goto tryagain;
@@ -195,9 +195,9 @@ moreinbuf:
} else if (sh->sm_cmd == SMC_UPDATE) {
su = (syncupdent_t *)buff;
if (sh->sm_p == IPPROTO_TCP) {
- printf(" TCP Update: age %lu state %d/%d\n",
+ printf(" TCP Update: age %lu state %d/%d\n",
su->sup_tcp.stu_age,
- su->sup_tcp.stu_state[0],
+ su->sup_tcp.stu_state[0],
su->sup_tcp.stu_state[1]);
}
} else {
@@ -212,7 +212,7 @@ moreinbuf:
goto tryagain;
}
-
+
if (n3 != n2) {
syslog(LOG_ERR, "Incomplete write (%d/%d)",
n3, n2);
@@ -226,7 +226,7 @@ moreinbuf:
/* move buffer to the front,we might need to make
* this more efficient, by using a rolling pointer
* over the buffer and only copying it, when
- * we are reaching the end
+ * we are reaching the end
*/
inbuf -= n2;
if (inbuf) {
diff --git a/contrib/ipfilter/tools/ipsyncs.c b/contrib/ipfilter/tools/ipsyncs.c
index 887eeab310c6..43692cd6a0d1 100644
--- a/contrib/ipfilter/tools/ipsyncs.c
+++ b/contrib/ipfilter/tools/ipsyncs.c
@@ -1,13 +1,13 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2001-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#if !defined(lint)
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipsyncs.c,v 1.5.2.4 2006/08/26 11:21:15 darrenr Exp $";
+static const char rcsid[] = "@(#)$Id$";
#endif
#include <sys/types.h>
#include <sys/time.h>
@@ -54,10 +54,10 @@ static void handleterm(int sig)
#define BUFFERLEN 1400
int main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
- int nfd = -1 , lfd = -1;
+ int nfd = -1 , lfd = -1;
int n1, n2, n3, magic, len, inbuf;
struct sockaddr_in sin;
struct sockaddr_in in;
@@ -66,14 +66,14 @@ char *argv[];
syncupdent_t *su;
synchdr_t *sh;
char *progname;
-
+
progname = strrchr(argv[0], '/');
if (progname) {
progname++;
} else {
progname = argv[0];
}
-
+
if (argc < 2) {
usage(progname);
exit(1);
@@ -86,7 +86,7 @@ char *argv[];
#endif
openlog(progname, LOG_PID, LOG_SECURITY);
-
+
lfd = open(IPSYNC_NAME, O_WRONLY);
if (lfd == -1) {
syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME);
@@ -101,14 +101,14 @@ char *argv[];
sin.sin_port = htons(atoi(argv[2]));
else
sin.sin_port = htons(43434);
- if (argc > 3)
+ if (argc > 3)
in.sin_addr.s_addr = inet_addr(argv[3]);
else
in.sin_addr.s_addr = 0;
in.sin_port = 0;
while(1) {
-
+
if (lfd != -1)
close(lfd);
if (nfd != -1)
@@ -119,7 +119,7 @@ char *argv[];
syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME);
goto tryagain;
}
-
+
nfd = socket(AF_INET, SOCK_DGRAM, 0);
if (nfd == -1) {
syslog(LOG_ERR, "Socket :%m");
@@ -135,20 +135,20 @@ char *argv[];
}
syslog(LOG_INFO, "Listening to %s", inet_ntoa(sin.sin_addr));
-
- inbuf = 0;
+
+ inbuf = 0;
while (1) {
- /*
+ /*
* XXX currently we do not check the source address
* of a datagram, this can be a security risk
*/
n1 = read(nfd, buff+inbuf, BUFFERLEN-inbuf);
-
+
printf("header : %d bytes read (header = %d bytes)\n",
- n1, sizeof(*sh));
-
+ n1, (int) sizeof(*sh));
+
if (n1 < 0) {
syslog(LOG_ERR, "Read error (header): %m");
goto tryagain;
@@ -161,8 +161,8 @@ char *argv[];
sleep(1);
continue;
}
-
- inbuf += n1;
+
+ inbuf += n1;
moreinbuf:
if (inbuf < sizeof(*sh)) {
@@ -171,7 +171,7 @@ moreinbuf:
sh = (synchdr_t *)buff;
len = ntohl(sh->sm_len);
- magic = ntohl(sh->sm_magic);
+ magic = ntohl(sh->sm_magic);
if (magic != SYNHDRMAGIC) {
syslog(LOG_ERR, "Invalid header magic %x",
@@ -199,8 +199,8 @@ moreinbuf:
printf(" table:Unknown(%d)", sh->sm_table);
printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num));
-#endif
-
+#endif
+
if (inbuf < sizeof(*sh) + len) {
continue; /* need more data */
goto tryagain;
@@ -213,9 +213,9 @@ moreinbuf:
} else if (sh->sm_cmd == SMC_UPDATE) {
su = (syncupdent_t *)buff;
if (sh->sm_p == IPPROTO_TCP) {
- printf(" TCP Update: age %lu state %d/%d\n",
+ printf(" TCP Update: age %lu state %d/%d\n",
su->sup_tcp.stu_age,
- su->sup_tcp.stu_state[0],
+ su->sup_tcp.stu_state[0],
su->sup_tcp.stu_state[1]);
}
} else {
@@ -231,7 +231,7 @@ moreinbuf:
goto tryagain;
}
-
+
if (n3 != n2) {
syslog(LOG_ERR, "%s: Incomplete write (%d/%d)",
IPSYNC_NAME, n3, n2);
@@ -245,7 +245,7 @@ moreinbuf:
/* move buffer to the front,we might need to make
* this more efficient, by using a rolling pointer
* over the buffer and only copying it, when
- * we are reaching the end
+ * we are reaching the end
*/
inbuf -= n2;
if (inbuf) {
diff --git a/contrib/ipfilter/tools/lex_var.h b/contrib/ipfilter/tools/lex_var.h
index 78c5efc4263d..eb59f5887cba 100644
--- a/contrib/ipfilter/tools/lex_var.h
+++ b/contrib/ipfilter/tools/lex_var.h
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2002 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
diff --git a/contrib/ipfilter/tools/lexer.c b/contrib/ipfilter/tools/lexer.c
index 989643c966b5..41b7896090ad 100644
--- a/contrib/ipfilter/tools/lexer.c
+++ b/contrib/ipfilter/tools/lexer.c
@@ -1,7 +1,7 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2002-2006 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
@@ -42,6 +42,7 @@ char yychars[YYBUFSIZ+1];
int yylineNum = 1;
int yypos = 0;
int yylast = -1;
+int yydictfixed = 0;
int yyexpectaddr = 0;
int yybreakondot = 0;
int yyvarnext = 0;
@@ -60,7 +61,7 @@ static void yystrtotext __P((char *));
static char *yytexttochar __P((void));
static int yygetc(docont)
-int docont;
+ int docont;
{
int c;
@@ -98,7 +99,7 @@ int docont;
static void yyunputc(c)
-int c;
+ int c;
{
if (c == '\n')
yylineNum--;
@@ -107,7 +108,7 @@ int c;
static int yyswallow(last)
-int last;
+ int last;
{
int c;
@@ -134,7 +135,7 @@ static char *yytexttochar()
static void yystrtotext(str)
-char *str;
+ char *str;
{
int len;
char *s;
@@ -150,7 +151,7 @@ char *str;
static char *yytexttostr(offset, max)
-int offset, max;
+ int offset, max;
{
char *str;
int i;
@@ -175,8 +176,11 @@ int offset, max;
int yylex()
{
+ static int prior = 0;
+ static int priornum = 0;
int c, n, isbuilding, rval, lnext, nokey = 0;
char *name;
+ int triedv6 = 0;
isbuilding = 0;
lnext = 0;
@@ -190,7 +194,8 @@ int yylex()
nextchar:
c = yygetc(0);
if (yydebug > 1)
- printf("yygetc = (%x) %c [%*.*s]\n", c, c, yypos, yypos, yytexttochar());
+ printf("yygetc = (%x) %c [%*.*s]\n",
+ c, c, yypos, yypos, yytexttochar());
switch (c)
{
@@ -209,6 +214,8 @@ nextchar:
sizeof(yytext[0]) * (yylast - yypos + 1));
}
yylast -= yypos;
+ if (yyexpectaddr == 2)
+ yyexpectaddr = 0;
yypos = 0;
lnext = 0;
nokey = 0;
@@ -232,6 +239,7 @@ nextchar:
if (lnext == 1) {
lnext = 0;
if ((isbuilding == 0) && !ISALNUM(c)) {
+ prior = c;
return c;
}
goto nextchar;
@@ -246,7 +254,7 @@ nextchar:
}
yyswallow('\n');
rval = YY_COMMENT;
- goto nextchar;
+ goto done;
case '$' :
if (isbuilding == 1) {
@@ -320,6 +328,9 @@ nextchar:
yybreakondot = 0;
yyvarnext = 0;
yytokentype = 0;
+ if (yydebug)
+ fprintf(stderr, "reset at EOF\n");
+ prior = 0;
return 0;
}
@@ -344,16 +355,21 @@ nextchar:
switch (c)
{
case '-' :
- if (yyexpectaddr)
- break;
- if (isbuilding == 1)
- break;
n = yygetc(0);
if (n == '>') {
isbuilding = 1;
goto done;
}
yyunputc(n);
+ if (yyexpectaddr) {
+ if (isbuilding == 1)
+ yyunputc(c);
+ else
+ rval = '-';
+ goto done;
+ }
+ if (isbuilding == 1)
+ break;
rval = '-';
goto done;
@@ -420,14 +436,21 @@ nextchar:
* 0000:0000:0000:0000:0000:0000:0000:0000
*/
#ifdef USE_INET6
- if (yyexpectaddr == 1 && isbuilding == 0 && (ishex(c) || c == ':')) {
+ if (yyexpectaddr != 0 && isbuilding == 0 &&
+ (ishex(c) || isdigit(c) || c == ':')) {
char ipv6buf[45 + 1], *s, oc;
int start;
+buildipv6:
start = yypos;
s = ipv6buf;
oc = c;
+ if (prior == YY_NUMBER && c == ':') {
+ sprintf(s, "%d", priornum);
+ s += strlen(s);
+ }
+
/*
* Perhaps we should implement stricter controls on what we
* swallow up here, but surely it would just be duplicating
@@ -451,7 +474,25 @@ nextchar:
}
#endif
- if (c == ':') {
+ if ((c == ':') && (rval != YY_IPV6) && (triedv6 == 0)) {
+#ifdef USE_INET6
+ yystr = yytexttostr(0, yypos - 1);
+ if (yystr != NULL) {
+ char *s;
+
+ for (s = yystr; *s && ishex(*s); s++)
+ ;
+ if (!*s && *yystr) {
+ isbuilding = 0;
+ c = *yystr;
+ free(yystr);
+ triedv6 = 1;
+ yypos = 1;
+ goto buildipv6;
+ }
+ free(yystr);
+ }
+#endif
if (isbuilding == 1) {
yyunputc(c);
goto done;
@@ -492,8 +533,8 @@ done:
yystr = yytexttostr(0, yypos);
if (yydebug)
- printf("isbuilding %d yyvarnext %d nokey %d\n",
- isbuilding, yyvarnext, nokey);
+ printf("isbuilding %d yyvarnext %d nokey %d fixed %d addr %d\n",
+ isbuilding, yyvarnext, nokey, yydictfixed, yyexpectaddr);
if (isbuilding == 1) {
wordtab_t *w;
@@ -502,7 +543,7 @@ done:
if ((yyvarnext == 0) && (nokey == 0)) {
w = yyfindkey(yystr);
- if (w == NULL && yywordtab != NULL) {
+ if (w == NULL && yywordtab != NULL && !yydictfixed) {
yyresetdict();
w = yyfindkey(yystr);
}
@@ -514,14 +555,19 @@ done:
rval = YY_STR;
}
- if (rval == YY_STR && yysavedepth > 0)
- yyresetdict();
+ if (rval == YY_STR) {
+ if (yysavedepth > 0 && !yydictfixed)
+ yyresetdict();
+ if (yyexpectaddr != 0)
+ yyexpectaddr = 0;
+ }
yytokentype = rval;
if (yydebug)
- printf("lexed(%s) [%d,%d,%d] => %d @%d\n", yystr, string_start,
- string_end, pos, rval, yysavedepth);
+ printf("lexed(%s) %d,%d,%d [%d,%d,%d] => %d @%d\n",
+ yystr, isbuilding, yyexpectaddr, yysavedepth,
+ string_start, string_end, pos, rval, yysavedepth);
switch (rval)
{
@@ -548,12 +594,15 @@ done:
yypos = 0;
}
+ if (rval == YY_NUMBER)
+ priornum = yylval.num;
+ prior = rval;
return rval;
}
static wordtab_t *yyfindkey(key)
-char *key;
+ char *key;
{
wordtab_t *w;
@@ -568,7 +617,7 @@ char *key;
char *yykeytostr(num)
-int num;
+ int num;
{
wordtab_t *w;
@@ -583,7 +632,7 @@ int num;
wordtab_t *yysettab(words)
-wordtab_t *words;
+ wordtab_t *words;
{
wordtab_t *save;
@@ -594,7 +643,7 @@ wordtab_t *words;
void yyerror(msg)
-char *msg;
+ char *msg;
{
char *txt, letter[2];
int freetxt = 0;
@@ -620,9 +669,31 @@ char *msg;
}
+void yysetfixeddict(newdict)
+ wordtab_t *newdict;
+{
+ if (yydebug)
+ printf("yysetfixeddict(%lx)\n", (u_long)newdict);
+
+ if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) {
+ fprintf(stderr, "%d: at maximum dictionary depth\n",
+ yylineNum);
+ return;
+ }
+
+ yysavewords[yysavedepth++] = yysettab(newdict);
+ if (yydebug)
+ printf("yysavedepth++ => %d\n", yysavedepth);
+ yydictfixed = 1;
+}
+
+
void yysetdict(newdict)
-wordtab_t *newdict;
+ wordtab_t *newdict;
{
+ if (yydebug)
+ printf("yysetdict(%lx)\n", (u_long)newdict);
+
if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) {
fprintf(stderr, "%d: at maximum dictionary depth\n",
yylineNum);
@@ -643,14 +714,15 @@ void yyresetdict()
if (yydebug)
printf("yysavedepth-- => %d\n", yysavedepth);
}
+ yydictfixed = 0;
}
#ifdef TEST_LEXER
int main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
int n;
diff --git a/contrib/ipfilter/tools/lexer.h b/contrib/ipfilter/tools/lexer.h
index d973ea42ae35..cff24b4eb402 100644
--- a/contrib/ipfilter/tools/lexer.h
+++ b/contrib/ipfilter/tools/lexer.h
@@ -1,16 +1,11 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 2002-2004 by Darren Reed.
+ * Copyright (C) 2012 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-typedef struct wordtab {
- char *w_word;
- int w_value;
-} wordtab_t;
-
#ifdef NO_YACC
#define YY_COMMENT 1000
#define YY_CMP_NE 1001
@@ -29,6 +24,7 @@ typedef struct wordtab {
extern wordtab_t *yysettab __P((wordtab_t *));
extern void yysetdict __P((wordtab_t *));
+extern void yysetfixeddict __P((wordtab_t *));
extern int yylex __P((void));
extern void yyerror __P((char *));
extern char *yykeytostr __P((int));