summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ipfw/ipfw.821
-rw-r--r--sbin/ipfw/ipfw.c14
-rw-r--r--sys/netinet/ip_fw.c6
-rw-r--r--sys/netinet/ip_fw.h2
4 files changed, 29 insertions, 14 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 2a58708..957d976 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -22,16 +22,13 @@ list
add
.Op Ar number
.Ar action
-.Op Ar log
+.Op log
.Ar proto
from
.Ar src
to
.Ar dst
-.Oo
-via
-.Ar name | ipno
-.Oc
+.Op via Ar name | ipno
.Op Ar options
.Sh DESCRIPTION
If used as shown in the first synopsis line, the
@@ -117,8 +114,7 @@ Divert packets that match this rule to the divert socket bound to port
The search terminates.
.El
.Pp
-When a packet matches a rule with the
-.Ar log
+When a packet matches a rule with the ``log''
keyword, a message will be printed on the console.
If the kernel was compiled with the
.Dv IP_FIREWALL_VERBOSE_LIMIT
@@ -150,7 +146,8 @@ and
.Ar dst :
.Pp
.Bl -hang -offset flag
-.It <address/mask> [ports]
+.It Ar <address/mask>
+.Op Ar ports
.El
.Pp
The
@@ -168,10 +165,14 @@ An ipnumber with a mask width of the form 1.2.3.4:255.255.240.0.
In this case all ip numbers from 1.2.0.0 to 1.2.15.255 will match.
.El
.Pp
+The sense of the match can be inverted by preceding an address with the
+``not'' modifier, causing all other addresses to be matched instead. This
+does not affect the selection of port numbers.
+.Pp
With the TCP and UDP
.Em protocols ,
-an optional
-.Em port
+optional
+.Em ports
may be specified as:
.Pp
.Bl -hang -offset flag
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index f1bb15a..fd1ab5d 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -162,7 +162,7 @@ show_ipfw(chain)
else
printf("%u", chain->fw_prot);
- printf(" from ");
+ printf(" from %s", chain->fw_flg & IP_FW_F_INVSRC ? "not " : "");
adrt=ntohl(chain->fw_smsk.s_addr);
if (adrt==ULONG_MAX && do_resolv) {
@@ -202,7 +202,7 @@ show_ipfw(chain)
}
}
- printf(" to ");
+ printf(" to %s", chain->fw_flg & IP_FW_F_INVDST ? "not " : "");
adrt=ntohl(chain->fw_dmsk.s_addr);
if (adrt==ULONG_MAX && do_resolv) {
@@ -685,6 +685,12 @@ add(ac,av)
if (ac && !strncmp(*av,"from",strlen(*av))) { av++; ac--; }
else show_usage("missing ``from''\n");
+ if (ac && !strncmp(*av,"not",strlen(*av))) {
+ rule.fw_flag |= IP_FW_F_INVSRC;
+ av++; ac--;
+ }
+ if (!ac) show_usage("Missing arguments\n");
+
fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av);
if (ac && isdigit(**av)) {
@@ -697,6 +703,10 @@ add(ac,av)
if (ac && !strncmp(*av,"to",strlen(*av))) { av++; ac--; }
else show_usage("missing ``to''\n");
+ if (ac && !strncmp(*av,"not",strlen(*av))) {
+ rule.fw_flag |= IP_FW_F_INVDST;
+ av++; ac--;
+ }
if (!ac) show_usage("Missing arguments\n");
fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av);
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index b62f6d7..f006bc6 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -320,11 +320,13 @@ ip_fw_chk(struct ip **pip, int hlen,
continue;
/* If src-addr doesn't match, not this rule. */
- if ((src.s_addr & f->fw_smsk.s_addr) != f->fw_src.s_addr)
+ if ((f->fw_flg & IP_FW_F_INVSRC) != 0
+ ^ (src.s_addr & f->fw_smsk.s_addr) != f->fw_src.s_addr)
continue;
/* If dest-addr doesn't match, not this rule. */
- if ((dst.s_addr & f->fw_dmsk.s_addr) != f->fw_dst.s_addr)
+ if ((f->fw_flg & IP_FW_F_INVDST) != 0
+ ^ (dst.s_addr & f->fw_dmsk.s_addr) != f->fw_dst.s_addr)
continue;
/* If a i/f name was specified, and we don't know */
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 8775521..bd5eeb7 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -64,6 +64,8 @@ struct ip_fw_chain {
/*
* Values for "flags" field .
*/
+#define IP_FW_F_INVSRC 0x0001 /* Invert sense of src check */
+#define IP_FW_F_INVDST 0x0002 /* Invert sense of dst check */
#define IP_FW_F_IN 0x0004 /* Inbound */
#define IP_FW_F_OUT 0x0008 /* Outbound */
OpenPOWER on IntegriCloud