Author: glebius
Date: Mon Feb  6 11:35:29 2012
New Revision: 231076
URL: http://svn.freebsd.org/changeset/base/231076

Log:
  Make the 'tcpwin' option of ipfw(8) accept ranges and lists.
  
  Submitted by: sem

Modified:
  head/sbin/ipfw/ipfw.8
  head/sbin/ipfw/ipfw2.c
  head/sys/netinet/ipfw/ip_fw2.c
  head/sys/netinet/ipfw/ip_fw_sockopt.c

Modified: head/sbin/ipfw/ipfw.8
==============================================================================
--- head/sbin/ipfw/ipfw.8       Mon Feb  6 11:04:36 2012        (r231075)
+++ head/sbin/ipfw/ipfw.8       Mon Feb  6 11:35:29 2012        (r231076)
@@ -1652,10 +1652,12 @@ option for details on matching fragmente
 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

Modified: head/sbin/ipfw/ipfw2.c
==============================================================================
--- head/sbin/ipfw/ipfw2.c      Mon Feb  6 11:04:36 2012        (r231075)
+++ head/sbin/ipfw/ipfw2.c      Mon Feb  6 11:35:29 2012        (r231076)
@@ -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 pcwidt
                                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;
 

Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c      Mon Feb  6 11:04:36 2012        
(r231075)
+++ head/sys/netinet/ipfw/ip_fw2.c      Mon Feb  6 11:35:29 2012        
(r231076)
@@ -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:

Modified: head/sys/netinet/ipfw/ip_fw_sockopt.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw_sockopt.c       Mon Feb  6 11:04:36 2012        
(r231075)
+++ head/sys/netinet/ipfw/ip_fw_sockopt.c       Mon Feb  6 11:35:29 2012        
(r231076)
@@ -569,7 +569,6 @@ check_ipfw_struct(struct ip_fw *rule, in
                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, in
                case O_IPTTL:
                case O_IPLEN:
                case O_TCPDATALEN:
+               case O_TCPWIN:
                case O_TAGGED:
                        if (cmdlen < 1 || cmdlen > 31)
                                goto bad_size;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to