summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ipfw/ipfw.850
-rw-r--r--sbin/ipfw/ipfw2.c70
-rw-r--r--sys/netinet/ip_fw2.c41
3 files changed, 120 insertions, 41 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 2968109..f63f788 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -707,7 +707,7 @@ The
or
.Cm all
keywords mean any protocol will match.
-.It Ar src No and Ar dst : ip-address | Cm { Ar ip-address Cm or ... } Op Ar ports
+.It Ar src No and Ar dst : ip-address | Cm { Ar ip-address Cm or ... } Op Oo Cm not Oc Ar ports
A single
.Ar ip-address
, or an
@@ -776,7 +776,7 @@ masks, and resort to the
format for contiguous masks, which is more compact and less
error-prone.
.El
-.It Ar ports : Oo Cm not Oc Bro Ar port | port Ns \&- Ns Ar port Ns Brc Op , Ns Ar ...
+.It Ar ports : Bro Ar port | port Ns \&- Ns Ar port Ns Brc Op , Ns Ar ports
For protocols which support port numbers (such as TCP and UDP), optional
.Cm ports
may be specified as one or more ports or port ranges, separated
@@ -827,10 +827,10 @@ The following match patterns can be used (listed in alphabetical order):
.Bl -tag -width indent
.It Cm bridged
Matches only bridged packets.
-.It Cm dst-ip Ar ip address
+.It Cm dst-ip Ar ip-address
Matches IP packets whose destination IP is one of the address(es)
specified as argument.
-.It Cm dst-port Ar source ports
+.It Cm dst-port Ar ports
Matches IP packets whose destination port is one of the port(s)
specified as argument.
.It Cm established
@@ -892,15 +892,21 @@ are mutually exclusive (in fact,
.Cm out
is implemented as
.Cm not in Ns No ).
-.It Cm ipid Ar id
+.It Cm ipid Ar id-list
Matches IP packets whose
.Cm ip_id
-field has value
-.Ar id .
-.It Cm iplen Ar len
+field has value included in
+.Ar id-list ,
+which is either a single value or a list of values or ranges
+specified in the same way as
+.Ar ports .
+.It Cm iplen Ar len-list
Matches IP packets whose total length, including header and data, is
-.Ar len
-bytes.
+in the set
+.Ar len-list ,
+which is either a single value or a list of values or ranges
+specified in the same way as
+.Ar ports .
.It Cm ipoptions Ar spec
Matches packets whose IP header contains the comma separated list of
options specified in
@@ -942,9 +948,12 @@ The supported IP types of service are:
The absence of a particular type may be denoted
with a
.Ql \&! .
-.It Cm ipttl Ar ttl
-Matches IP packets whose time to live is
-.Ar ttl .
+.It Cm ipttl Ar ttl-list
+Matches IP packets whose time to live is included in
+.Ar ttl-list ,
+which is either a single value or a list of values or ranges
+specified in the same way as
+.Ar ports .
.It Cm ipversion Ar ver
Matches IP packets whose IP version field is
.Ar ver .
@@ -1762,15 +1771,20 @@ The sysctl variable
.Em net.link.ether.ipfw
has no effect there.
.It Options
-The following options are not supported in
-.Nm ipfw1
+In
+.Nm ipfw1 ,
+the following options only accept a single value as an argument:
+.Pp
+.Cm ipid, iplen, ipttl
+.Pp
+The following options are not implemented by
+.Nm ipfw1 :
.Pp
.Cm dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port.
.Pp
-Additionally, the following options are not supported in
+Additionally, the RELENG_4 version of
.Nm ipfw1
-(RELENG_4)
-rules:
+does not implement the following options:
.Pp
.Cm ipid, iplen, ipprecedence, iptos, ipttl,
.Cm ipversion, tcpack, tcpseq, tcpwin .
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index f0a1030..3a3ff3a 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -418,13 +418,37 @@ print_newports(ipfw_insn_u16 *cmd, int proto, int opcode)
{
u_int16_t *p = cmd->ports;
int i;
- char *sep= " ";
+ char *sep;
if (cmd->o.len & F_NOT)
printf(" not");
- if (opcode != 0)
- printf ("%s", opcode == O_MAC_TYPE ? " mac-type" :
- (opcode == O_IP_DSTPORT ? " dst-port" : " src-port"));
+ if (opcode != 0) {
+ switch (opcode) {
+ case O_IP_DSTPORT:
+ sep = "dst-port";
+ break;
+ case O_IP_SRCPORT:
+ sep = "src-port";
+ break;
+ case O_IPID:
+ sep = "ipid";
+ break;
+ case O_IPLEN:
+ sep = "iplen";
+ break;
+ case O_IPTTL:
+ sep = "ipttl";
+ break;
+ case O_MAC_TYPE:
+ sep = "mac-type";
+ break;
+ default:
+ sep = "???";
+ break;
+ }
+ printf (" %s", sep);
+ }
+ sep = " ";
for (i = F_LEN((ipfw_insn *)cmd) - 1; i > 0; i--, p += 2) {
printf(sep);
print_port(proto, p[0]);
@@ -1096,11 +1120,19 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
break;
case O_IPID:
- printf(" ipid %u", cmd->arg1 );
+ if (F_LEN(cmd) == 1)
+ printf(" ipid %u", cmd->arg1 );
+ else
+ print_newports((ipfw_insn_u16 *)cmd, 0,
+ O_IPID);
break;
case O_IPTTL:
- printf(" ipttl %u", cmd->arg1 );
+ if (F_LEN(cmd) == 1)
+ printf(" ipttl %u", cmd->arg1 );
+ else
+ print_newports((ipfw_insn_u16 *)cmd, 0,
+ O_IPTTL);
break;
case O_IPVER:
@@ -1112,7 +1144,11 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
break;
case O_IPLEN:
- printf(" iplen %u", cmd->arg1 );
+ if (F_LEN(cmd) == 1)
+ printf(" iplen %u", cmd->arg1 );
+ else
+ print_newports((ipfw_insn_u16 *)cmd, 0,
+ O_IPLEN);
break;
case O_IPOPT:
@@ -2971,19 +3007,31 @@ read_options:
case TOK_IPTTL:
NEED1("ipttl requires TTL");
- fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
+ if (strpbrk(*av, "-,")) {
+ if (!add_ports(cmd, *av, 0, O_IPTTL))
+ errx(EX_DATAERR, "invalid ipttl %s", *av);
+ } else
+ fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0));
ac--; av++;
break;
case TOK_IPID:
- NEED1("ipid requires length");
- fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0));
+ NEED1("ipid requires id");
+ if (strpbrk(*av, "-,")) {
+ if (!add_ports(cmd, *av, 0, O_IPID))
+ errx(EX_DATAERR, "invalid ipid %s", *av);
+ } else
+ fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0));
ac--; av++;
break;
case TOK_IPLEN:
NEED1("iplen requires length");
- fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0));
+ if (strpbrk(*av, "-,")) {
+ if (!add_ports(cmd, *av, 0, O_IPLEN))
+ errx(EX_DATAERR, "invalid ip len %s", *av);
+ } else
+ fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0));
ac--; av++;
break;
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 95a153e..1af01da 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -1730,17 +1730,30 @@ check_body:
match = (hlen > 0 && cmd->arg1 == ip->ip_v);
break;
- case O_IPTTL:
- match = (hlen > 0 && cmd->arg1 == ip->ip_ttl);
- break;
-
case O_IPID:
- match = (hlen > 0 &&
- cmd->arg1 == ntohs(ip->ip_id));
- break;
-
case O_IPLEN:
- match = (hlen > 0 && cmd->arg1 == ip_len);
+ case O_IPTTL:
+ if (hlen > 0) { /* only for IP packets */
+ uint16_t x;
+ uint16_t *p;
+ int i;
+
+ if (cmd->opcode == O_IPLEN)
+ x = ip_len;
+ else if (cmd->opcode == O_IPTTL)
+ x = ip->ip_ttl;
+ else /* must be IPID */
+ x = ntohs(ip->ip_id);
+ if (cmdlen == 1) {
+ match = (cmd->arg1 == x);
+ break;
+ }
+ /* otherwise we have ranges */
+ p = ((ipfw_insn_u16 *)cmd)->ports;
+ i = cmdlen - 1;
+ for (; !match && i>0; i--, p += 2)
+ match = (x >= p[0] && x <= p[1]);
+ }
break;
case O_IPPRECEDENCE:
@@ -2371,11 +2384,8 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_IN:
case O_FRAG:
case O_IPOPT:
- case O_IPLEN:
- case O_IPID:
case O_IPTOS:
case O_IPPRECEDENCE:
- case O_IPTTL:
case O_IPVER:
case O_TCPWIN:
case O_TCPFLAGS:
@@ -2440,6 +2450,13 @@ check_ipfw_struct(struct ip_fw *rule, int size)
goto bad_size;
break;
+ case O_IPID:
+ case O_IPTTL:
+ case O_IPLEN:
+ if (cmdlen < 1 || cmdlen > 31)
+ goto bad_size;
+ break;
+
case O_MAC_TYPE:
case O_IP_SRCPORT:
case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
OpenPOWER on IntegriCloud