All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brad Fisher <brad@info-link.net>
To: netfilter-devel@lists.netfilter.org
Subject: Patch with additional options for quota match
Date: Wed, 16 Apr 2003 16:24:37 -0500	[thread overview]
Message-ID: <3E9DCA15.40C99A6C@info-link.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 949 bytes --]

I have made up a small patch for the quota match by Sam Johnston to add
a couple of options I find useful - negated matching and the option to
count total packet size (data + headers) instead of just data size.
Examples:

# Old behavior, ACCEPT packets UNTIL 5000000 quota has been consumed
iptables -A INPUT -m quota --quota 5000000 -j ACCEPT

# Negated match, DROP packets AFTER 5000000 quota has been consumed
#  Does not count packet headers when calculating the quota.
#  Lets packets pass as long as the remaining quota > 0
iptables -A INPUT -m quota --quota ! 5000000 -j DROP

# Negated match, DROP packets AFTER 5000000 quota has been consumed
#  Packet headers are counted in the quota.
#  Lets packets pass as long as the remaining quota > 0
iptables -A INPUT -m quota --quota ! 5000000 --count-headers -j DROP

The patches should apply cleanly to the iptables-1.2.7a and
patch-o-matic-20030107 distributions.

Brad Fisher
Info Link Inc.


[-- Attachment #2: iptables-libipt_quota.diff --]
[-- Type: text/plain, Size: 3422 bytes --]

--- iptables-1.2.7a/extensions/libipt_quota.c	Wed May 29 08:08:16 2002
+++ iptables-1.2.7a-imq/extensions/libipt_quota.c	Wed Apr 16 15:11:05 2003
@@ -2,6 +2,7 @@
  * Shared library add-on to iptables to add quota support
  *
  * Sam Johnston <samj@samj.net>
+ * (Modified to support negated matches and add option to count headers by Brad Fisher (brad@info-link.net))
  */
 #include <stdio.h>
 #include <stdlib.h>
@@ -13,6 +14,7 @@
 
 static struct option opts[] = {
         {"quota", 1, 0, '1'},
+        {"count-headers", 0, 0, '2'},
         {0}
 };
 
@@ -21,7 +23,8 @@
 help(void)
 {
         printf("quota options:\n"
-               " --quota quota                  quota (bytes)\n" "\n");
+               " --quota [!] quota              quota (bytes)\n"
+               " --count-headers                count headers as well as data\n" "\n");
 }
 
 /* initialise match */
@@ -37,7 +40,18 @@
 print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric)
 {
         struct ipt_quota_info *q = (struct ipt_quota_info *) match->data;
-        printf("quota: %llu bytes", (unsigned long long) q->quota);
+        char *negate = "";
+        char *headers = "";
+
+        if (q->flags & IPT_QUOTA_FLAG_NEGATE) {
+          negate = "!";
+        }
+
+        if (q->flags & IPT_QUOTA_FLAG_COUNT_FULL) {
+          headers = " (incl. headers)";
+        }
+
+        printf("quota: %s%llu bytes%s", negate, (unsigned long long) q->quota, headers);
 }
 
 /* save matchinfo */
@@ -45,14 +59,28 @@
 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
 {
         struct ipt_quota_info *q = (struct ipt_quota_info *) match->data;
-        printf("--quota %llu ", (unsigned long long) q->quota);
+
+        printf("--quota ");
+        if (q->flags & IPT_QUOTA_FLAG_NEGATE) {
+                printf("! ");
+        }
+        printf("%llu ", (unsigned long long) q->quota);
+
+        if (q->flags & IPT_QUOTA_FLAG_COUNT_FULL) {
+                printf("--count-headers ");
+        }
 }
 
 /* parse quota option */
 static int
 parse_quota(const char *s, u_int64_t * quota)
 {
-        *quota = strtoull(s, (char **) NULL, 10);
+        /* Don't allow negative quotas... Not perfect since it doesn't skip whitespace */
+        if (s && (*s == '-')) {
+                *quota = -1;
+        } else {
+                *quota = strtoull(s, (char **) NULL, 10);
+        }
 
 #ifdef DEBUG_IPT_QUOTA
         printf("Quota: %llu\n", *quota);
@@ -74,12 +102,20 @@
 
         switch (c) {
         case '1':
-                if (check_inverse(optarg, &invert, NULL, 0))
-                        exit_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
-                if (!parse_quota(optarg, &info->quota))
+                check_inverse(optarg, &invert, &optind, 0);
+                if (invert) {
+                        info->flags |= IPT_QUOTA_FLAG_NEGATE;
+                }
+                if (!parse_quota(argv[optind-1], &info->quota))
                         exit_error(PARAMETER_PROBLEM,
                                    "bad quota: '%s'", optarg);
                 break;
+
+        case '2':
+                if (check_inverse(optarg, &invert, NULL, 0))
+                        exit_error(PARAMETER_PROBLEM, "count-headers: unexpected '!'");
+                info->flags |= IPT_QUOTA_FLAG_COUNT_FULL;
+                break;
 
         default:
                 return 0;

[-- Attachment #3: patch-o-matic-20030107-quota.diff --]
[-- Type: text/plain, Size: 4396 bytes --]

diff -urN patch-o-matic-20030107/base/quota.patch patch-o-matic-20030107-imq/base/quota.patch
--- patch-o-matic-20030107/base/quota.patch	Mon Dec  3 16:22:56 2001
+++ patch-o-matic-20030107-imq/base/quota.patch	Wed Apr 16 15:46:43 2003
@@ -1,26 +1,35 @@
-diff -urN kernel-source-2.4.16/include/linux/netfilter_ipv4/ipt_quota.h kernel-source-2.4.16-samj/include/linux/netfilter_ipv4/ipt_quota.h
---- kernel-source-2.4.16/include/linux/netfilter_ipv4/ipt_quota.h	Thu Jan  1 10:00:00 1970
-+++ kernel-source-2.4.16-samj/include/linux/netfilter_ipv4/ipt_quota.h	Mon Dec  3 21:43:07 2001
-@@ -0,0 +1,11 @@
+diff -urN linux-2.4.20-clean/include/linux/netfilter_ipv4/ipt_quota.h linux-2.4.20/include/linux/netfilter_ipv4/ipt_quota.h
+--- linux-2.4.20-clean/include/linux/netfilter_ipv4/ipt_quota.h	Wed Dec 31 18:00:00 1969
++++ linux-2.4.20/include/linux/netfilter_ipv4/ipt_quota.h	Wed Apr 16 13:35:52 2003
+@@ -0,0 +1,19 @@
 +#ifndef _IPT_QUOTA_H
 +#define _IPT_QUOTA_H
 +
 +/* print debug info in both kernel/netfilter module & iptable library */
 +//#define DEBUG_IPT_QUOTA
 +
++#define IPT_QUOTA_FLAG_NEGATE 1
++#define IPT_QUOTA_FLAG_COUNT_FULL 2
++
 +struct ipt_quota_info {
-+        u_int64_t quota;
++        u_int64_t quota;	/* Remaining bytes to allow */
++	u_int16_t flags;	/* Bitmask: */
++				/*   Bit 0 - negate match if set (matches if quota == 0) */
++				/*           normal match if not set (matches if quota > 0) */
++				/*   Bit 1 - include entire packet (headers + data) in count if set */
++				/*           only count data size if not set */
 +};
 +
 +#endif /*_IPT_QUOTA_H*/
-diff -urN kernel-source-2.4.16/net/ipv4/netfilter/ipt_quota.c kernel-source-2.4.16-samj/net/ipv4/netfilter/ipt_quota.c
---- kernel-source-2.4.16/net/ipv4/netfilter/ipt_quota.c	Thu Jan  1 10:00:00 1970
-+++ kernel-source-2.4.16-samj/net/ipv4/netfilter/ipt_quota.c	Mon Dec  3 21:42:08 2001
-@@ -0,0 +1,81 @@
+diff -urN linux-2.4.20-clean/net/ipv4/netfilter/ipt_quota.c linux-2.4.20/net/ipv4/netfilter/ipt_quota.c
+--- linux-2.4.20-clean/net/ipv4/netfilter/ipt_quota.c	Wed Dec 31 18:00:00 1969
++++ linux-2.4.20/net/ipv4/netfilter/ipt_quota.c	Wed Apr 16 14:07:56 2003
+@@ -0,0 +1,99 @@
 +/* 
 + * netfilter module to enforce network quotas
 + *
 + * Sam Johnston <samj@samj.net>
++ * (Modified to support negation by Brad Fisher <brad@info-link.net>)
 + */
 +#include <linux/module.h>
 +#include <linux/skbuff.h>
@@ -44,6 +53,10 @@
 +
 +        struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
 +
++	if (q->flags & IPT_QUOTA_FLAG_COUNT_FULL) {
++		datalen = skb->len;
++	}
++
 +        spin_lock_bh(&quota_lock);
 +
 +        if (q->quota >= datalen) {
@@ -51,20 +64,33 @@
 +                q->quota -= datalen;
 +                spin_unlock_bh(&quota_lock);
 +
++		if ((q->flags & IPT_QUOTA_FLAG_NEGATE) == 0) {
 +#ifdef DEBUG_IPT_QUOTA
-+                printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
++	                printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
 +#endif
-+                return 1;
++        	        return 1;
++		} else {
++#ifdef DEBUG_IPT_QUOTA
++		        printk("IPT Quota Failed: !%llu datlen %d \n", q->quota, datalen);
++#endif
++			return 0;
++		}
 +        }
 +
 +        /* so we do not allow even small packets from now on */
 +        q->quota = 0;
 +
++        spin_unlock_bh(&quota_lock);
++	if ((q->flags & IPT_QUOTA_FLAG_NEGATE)) {
++#ifdef DEBUG_IPT_QUOTA
++                printk("IPT Quota OK: %llu datlen !%d \n", q->quota, datalen);
++#endif
++		return 1;
++	}
++
 +#ifdef DEBUG_IPT_QUOTA
 +        printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
 +#endif
-+
-+        spin_unlock_bh(&quota_lock);
 +        return 0;
 +}
 +
diff -urN patch-o-matic-20030107/base/quota.patch.help patch-o-matic-20030107-imq/base/quota.patch.help
--- patch-o-matic-20030107/base/quota.patch.help	Mon Dec  3 16:22:56 2001
+++ patch-o-matic-20030107-imq/base/quota.patch.help	Wed Apr 16 15:49:37 2003
@@ -5,6 +5,9 @@
 quotas by decrementing a byte counter with each packet.
 
 Supported options are:
---quota <bytes>
-  The quota in bytes.
-
+--quota [!] <bytes>
+  The quota in bytes.  The normal form matches all packets up to the
+    quota, while the negated form only matches after quota bytes have
+    been examined by the rule.
+--count-headers
+  Counts headers as well as data (default only counts data)

             reply	other threads:[~2003-04-16 21:24 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-04-16 21:24 Brad Fisher [this message]
2003-04-27 12:40 ` Patch with additional options for quota match Harald Welte
2003-04-28 21:09   ` Sam Johnston
2003-04-28 21:49     ` Brad Fisher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3E9DCA15.40C99A6C@info-link.net \
    --to=brad@info-link.net \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.