summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ipfw/ipfw.816
-rw-r--r--sbin/ipfw/ipfw.c13
-rw-r--r--sys/netinet/ip_fw.c38
3 files changed, 62 insertions, 5 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index b3eec6c..c070b2a 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -289,6 +289,12 @@ and the length of the port list is limited to
.Pa /usr/src/sys/netinet/ip_fw.h )
ports.
.Pp
+Fragmented packets which have a non-zero offset (i.e. not the first
+fragment) will never match a rule which has one or more port
+specifications. See the
+.Ar frag
+option for details on matching fragmented packets.
+.Pp
Rules can apply to packets when they are incoming, or outgoing, or both.
The
.Ar in
@@ -360,6 +366,10 @@ Additional
.It frag
Matches if the packet is a fragment and this is not the first fragment
of the datagram.
+.Ar frag
+may not be used in conjunction with either
+.Ar tcpflags
+or TCP/UDP port specifications.
.It in
Matches if this packet was on the way in.
.It out
@@ -399,6 +409,12 @@ and
.Ar urg .
The absence of a particular flag may be denoted
with a ``!''.
+A rule which contains a
+.Ar tcpflags
+specification can never match a fragmented packet which has
+a non-zero offset. See the
+.Ar frag
+option for details on matching fragmented packets.
.It icmptypes Ar types
Matches if the ICMP type is in the list
.Ar types .
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index 29300d1..5663ed7 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -16,7 +16,7 @@
*
* NEW command line interface for IP firewall facility
*
- * $Id: ipfw.c,v 1.52 1998/01/08 00:27:31 alex Exp $
+ * $Id: ipfw.c,v 1.53 1998/01/08 03:03:50 alex Exp $
*
*/
@@ -502,7 +502,7 @@ show_usage(const char *fmt, ...)
" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
" extras:\n"
-" fragment\n"
+" fragment (may not be used with ports or tcpflags)\n"
" in\n"
" out\n"
" {xmit|recv|via} {iface|ip|any}\n"
@@ -1108,6 +1108,15 @@ badviacombo:
} else if ((rule.fw_flg & IP_FW_F_OIFACE) && (rule.fw_flg & IP_FW_F_IN))
show_usage("can't check xmit interface of incoming packets");
+ /* frag may not be used in conjunction with ports or TCP flags */
+ if (rule.fw_flg & IP_FW_F_FRAG) {
+ if (rule.fw_tcpf || rule.fw_tcpnf)
+ show_usage(EX_USAGE, "can't mix 'frag' and tcpflags");
+
+ if (rule.fw_nports)
+ show_usage(EX_USAGE, "can't mix 'frag' and port specifications");
+ }
+
if (!do_quiet)
show_ipfw(&rule, 10, 10);
i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 21011c2..854879a 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -12,7 +12,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.76 1998/02/06 12:13:51 eivind Exp $
+ * $Id: ip_fw.c,v 1.77 1998/02/09 06:10:10 eivind Exp $
*/
/*
@@ -459,8 +459,18 @@ ip_fw_chk(struct ip **pip, int hlen,
if (offset == 1) /* cf. RFC 1858 */
goto bogusfrag;
- if (offset != 0) /* Flags, ports aren't valid */
+ if (offset != 0) {
+ /*
+ * TCP flags and ports aren't available in this
+ * packet -- if this rule specified either one,
+ * we consider the rule a non-match.
+ */
+ if (f->fw_nports != 0 ||
+ f->fw_tcpf != f->fw_tcpnf)
+ continue;
+
break;
+ }
PULLUP_TO(hlen + 14);
tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
@@ -474,8 +484,17 @@ ip_fw_chk(struct ip **pip, int hlen,
{
struct udphdr *udp;
- if (offset != 0) /* Ports aren't valid */
+ if (offset != 0) {
+ /*
+ * Port specification is unavailable -- if this
+ * rule specifies a port, we consider the rule
+ * a non-match.
+ */
+ if (f->fw_nports != 0)
+ continue;
+
break;
+ }
PULLUP_TO(hlen + 4);
udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl);
src_port = ntohs(udp->uh_sport);
@@ -868,6 +887,19 @@ check_ipfw_struct(struct ip_fw *frwl)
return(NULL);
}
+ if ((frwl->fw_flg & IP_FW_F_FRAG) &&
+ (frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
+ if (frwl->fw_nports) {
+ dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
+ return(NULL);
+ }
+ if (frwl->fw_prot == IPPROTO_TCP &&
+ frwl->fw_tcpf != frwl->fw_tcpnf) {
+ dprintf(("%s cannot mix 'frag' and TCP flags\n", err_prefix));
+ return(NULL);
+ }
+ }
+
/* Check command specific stuff */
switch (frwl->fw_flg & IP_FW_F_COMMAND)
{
OpenPOWER on IntegriCloud