Hi there,

Current ipfw implementation doesn't allow for matching IP packets
by their precedence field while there exist real-life cases when
it would be a rather useful feature.

Please review the following patches against -current that add the
feature: ipfw.diff for the utility, ip_fw.diff for kernel.
As for me, they worked without any problems.

-- 
Yar
diff -u --exclude=*orig /usr/src/sbin/ipfw/ipfw.8 ipfw/ipfw.8
--- /usr/src/sbin/ipfw/ipfw.8   Thu Jun  7 00:56:56 2001
+++ ipfw/ipfw.8 Sun Jul  1 15:03:47 2001
@@ -667,6 +667,9 @@
 .It Cm ipversion Ar ver
 Match if the IP header version is
 .Ar ver .
+.It Cm ipprecedence Ar precedence
+Match if the numeric value of IP datagram's precedence is equal to
+.Ar precedence .
 .It Cm iptos Ar spec
 Match if the IP header contains the comma separated list of
 service types specified in
diff -u --exclude=*orig /usr/src/sbin/ipfw/ipfw.c ipfw/ipfw.c
--- /usr/src/sbin/ipfw/ipfw.c   Tue Jun  5 03:56:26 2001
+++ ipfw/ipfw.c Sun Jul  1 15:34:42 2001
@@ -432,6 +432,8 @@
                printf(" iplen %u", chain->fw_iplen);
        if (chain->fw_ipflg & IP_FW_IF_IPID)
                printf(" ipid %#x", chain->fw_ipid);
+       if (chain->fw_ipflg & IP_FW_IF_IPPRE)
+               printf(" ipprecedence %u", (chain->fw_iptos & 0xe0) >> 5);
 
        if (chain->fw_ipflg & IP_FW_IF_IPTOS) {
                int     _opt_printed = 0;
@@ -909,6 +911,7 @@
 "    ipoptions [!]{ssrr|lsrr|rr|ts}, ...\n"
 "    iplen {length}\n"
 "    ipid {identification number}\n"
+"    ipprecedence {precedence}\n"
 "    iptos [!]{lowdelay|throughput|reliability|mincost|congestion}, ...\n"
 "    ipttl {time to live}\n"
 "    ipversion {version number}\n"
@@ -2058,6 +2061,24 @@
                                show_usage("argument to ipid out of range");
                        rule.fw_ipflg |= IP_FW_IF_IPID;
                        rule.fw_ipid = (u_short)ipid;
+                       av++; ac--;
+               } else if (!strncmp(*av, "ipprecedence", strlen(*av))) {
+                       u_long ippre;
+                       char *c;
+
+                       av++; ac--;
+                       if (!ac)
+                               show_usage("missing argument"
+                                       " for ``ipprecedence''");
+                       ippre = strtoul(*av, &c, 0);
+                       if (*c != '\0')
+                               show_usage("argument to ipprecedence"
+                                       " must be numeric");
+                       if (ippre > 7)
+                               show_usage("argument to ipprecedence"
+                                       " out of range");
+                       rule.fw_ipflg |= IP_FW_IF_IPPRE;
+                       rule.fw_iptos |= ((u_short)ippre) << 5;
                        av++; ac--;
                } else if (!strncmp(*av, "iptos", strlen(*av))) {
                        av++; ac--;
diff -u --exclude=*orig /usr/src/sys/netinet.orig/ip_fw.c netinet/ip_fw.c
--- /usr/src/sys/netinet.orig/ip_fw.c   Fri Apr  6 10:52:25 2001
+++ netinet/ip_fw.c     Sun Jul  1 15:40:52 2001
@@ -373,7 +373,7 @@
        u_int flags = (ip->ip_tos & 0x1f);
        u_char opts, nopts, nopts_sve;
 
-       opts = f->fw_iptos;
+       opts = (f->fw_iptos & 0x1f);
        nopts = nopts_sve = f->fw_ipntos;
 
        while (flags != 0) {
@@ -1162,6 +1162,9 @@
                if (f->fw_ipflg & IP_FW_IF_IPLEN && f->fw_iplen != ip_len)
                        continue;
                if (f->fw_ipflg & IP_FW_IF_IPID && f->fw_ipid != ntohs(ip->ip_id))
+                       continue;
+               if (f->fw_ipflg & IP_FW_IF_IPPRE &&
+                    (f->fw_iptos & 0xe0) != (ip->ip_tos & 0xe0))
                        continue;
                if (f->fw_ipflg & IP_FW_IF_IPTOS && !iptos_match(ip, f))
                        continue;
diff -u --exclude=*orig /usr/src/sys/netinet.orig/ip_fw.h netinet/ip_fw.h
--- /usr/src/sys/netinet.orig/ip_fw.h   Tue Feb 13 17:12:04 2001
+++ netinet/ip_fw.h     Sun Jul  1 15:27:24 2001
@@ -234,7 +234,8 @@
 #define IP_FW_IF_IPTOS 0x00000800      /* ip type of service           */
 #define IP_FW_IF_IPTTL 0x00001000      /* ip time to live              */
 #define IP_FW_IF_IPVER 0x00002000      /* ip version                   */
-#define IP_FW_IF_IPMSK 0x00003f00      /* mask of all ip values        */
+#define IP_FW_IF_IPPRE 0x00004000      /* ip precedence                */
+#define IP_FW_IF_IPMSK 0x00007f00      /* mask of all ip values        */
 
 #define IP_FW_IF_MSK   0x0000ffff      /* All possible bits mask       */
 

Reply via email to