summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ipfw/ipfw.810
-rw-r--r--sbin/ipfw/ipfw2.c15
-rw-r--r--sys/netinet/ipfw/ip_fw2.c18
-rw-r--r--sys/netinet/ipfw/ip_fw_sockopt.c2
4 files changed, 35 insertions, 10 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 0270802..3badfa9 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1652,10 +1652,12 @@ option for details on matching fragmented packets.
TCP packets only.
Match if the TCP header sequence number field is set to
.Ar seq .
-.It Cm tcpwin Ar win
-TCP packets only.
-Match if the TCP header window field is set to
-.Ar win .
+.It Cm tcpwin Ar tcpwin-list
+Matches TCP packets whose header window field is set to
+.Ar tcpwin-list ,
+which is either a single value or a list of values or ranges
+specified in the same way as
+.Ar ports .
.It Cm tcpoptions Ar spec
TCP packets only.
Match if the TCP header contains the comma separated list of
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 6b0e0f0..ac0632e 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -512,6 +512,7 @@ static struct _s_x _port_name[] = {
{"ipttl", O_IPTTL},
{"mac-type", O_MAC_TYPE},
{"tcpdatalen", O_TCPDATALEN},
+ {"tcpwin", O_TCPWIN},
{"tagged", O_TAGGED},
{NULL, 0}
};
@@ -1480,7 +1481,11 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
break;
case O_TCPWIN:
- printf(" tcpwin %d", ntohs(cmd->arg1));
+ if (F_LEN(cmd) == 1)
+ printf(" tcpwin %u", cmd->arg1);
+ else
+ print_newports((ipfw_insn_u16 *)cmd, 0,
+ O_TCPWIN);
break;
case O_TCPACK:
@@ -3447,8 +3452,12 @@ read_options:
case TOK_TCPWIN:
NEED1("tcpwin requires length");
- fill_cmd(cmd, O_TCPWIN, 0,
- htons(strtoul(*av, NULL, 0)));
+ if (strpbrk(*av, "-,")) {
+ if (!add_ports(cmd, *av, 0, O_TCPWIN))
+ errx(EX_DATAERR, "invalid tcpwin len %s", *av);
+ } else
+ fill_cmd(cmd, O_TCPWIN, 0,
+ strtoul(*av, NULL, 0));
av++;
break;
diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
index 12a7fb9..82ffb98 100644
--- a/sys/netinet/ipfw/ip_fw2.c
+++ b/sys/netinet/ipfw/ip_fw2.c
@@ -1650,8 +1650,22 @@ do { \
break;
case O_TCPWIN:
- match = (proto == IPPROTO_TCP && offset == 0 &&
- cmd->arg1 == TCP(ulp)->th_win);
+ if (proto == IPPROTO_TCP && offset == 0) {
+ uint16_t x;
+ uint16_t *p;
+ int i;
+
+ x = ntohs(TCP(ulp)->th_win);
+ 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_ESTAB:
diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
index dce3fdc..1302452 100644
--- a/sys/netinet/ipfw/ip_fw_sockopt.c
+++ b/sys/netinet/ipfw/ip_fw_sockopt.c
@@ -569,7 +569,6 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_IPPRECEDENCE:
case O_IPVER:
case O_SOCKARG:
- case O_TCPWIN:
case O_TCPFLAGS:
case O_TCPOPTS:
case O_ESTAB:
@@ -679,6 +678,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_IPTTL:
case O_IPLEN:
case O_TCPDATALEN:
+ case O_TCPWIN:
case O_TAGGED:
if (cmdlen < 1 || cmdlen > 31)
goto bad_size;
OpenPOWER on IntegriCloud