Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Nov 2004 12:17:21 -0800
From:      "David Schwartz" <davids@webmaster.com>
To:        <freebsd-ipfw@freebsd.org>
Subject:   PATCH: Add creation time to dynamic firewall rules
Message-ID:  <MDEHLPKNGKAHNMBLJOLKGEJPABAB.davids@webmaster.com>

next in thread | raw e-mail | index | archive | help

	FreeBSD/ipfw2 currently keeps the expiration time for dynamic firewall
rules (obviously), but it does not track the creation time. The attached
patch keeps the creation time and adds a flag to 'ipfw' to show the time
since creation instead of the time until expiration.

	This is useful for two reasons. First, knowing how long a connection has
been around gives you an idea of how stable it is. Second, the packet/byte
counters are not as meaningful without knowing what time period they
cover -- with both the counters and the time frame, you can estimate the
bandwidth consumption of the connection.

	The cost is four bytes of memory per dynamic firewall rule. This is both
consumed kernel memory for the dynamic rule table and cost of copying out
the rules when they're requested. In addition, retrieving the dynamic
firewall rules requries an extra computation to relativize the time (as is
done for expiration time now). Even for a large firewall with, say, 10,000
states, this is still a minimal amount of memory (40Kb).

	This patch is tested and is offered under the FreeBSD license. I would like
to see it included in the distribution. The patch is against 5_STABLE, and
the versions of the various files patched are in the patch headers. The
patch has been tested.

	Note that both copies of ip_fw.h must be patched.

	David Schwartz
	<davids@webmaster.com>

--


--- ip_fw.h	1.89.2.2 2004/10/03 17:04:40
+++ ip_fw.h	Fri Nov 26 18:51:15 2004
@@ -353,6 +353,7 @@ struct _ipfw_dyn_rule {
 	u_int64_t	bcnt;		/* byte match counter		*/
 	struct ipfw_flow_id id;		/* (masked) flow id		*/
 	u_int32_t	expire;		/* expire time			*/
+	u_int32_t	created;	/* creation time		*/
 	u_int32_t	bucket;		/* which bucket in hash table	*/
 	u_int32_t	state;		/* state of this rule (typically a
 					 * combination of TCP flags)

--- ip_fw2.c	1.54.2.3 2004/09/17 14:49:08
+++ ip_fw2.c	Fri Nov 26 18:56:41 2004
@@ -1037,6 +1037,7 @@ add_dyn_rule(struct ipfw_flow_id *id, u_

 	r->id = *id;
 	r->expire = time_second + dyn_syn_lifetime;
+	r->created = time_second;
 	r->rule = rule;
 	r->dyn_type = dyn_type;
 	r->pcnt = r->bcnt = 0;
@@ -3089,6 +3090,9 @@ ipfw_getrules(struct ip_fw_chain *chain,
 					dst->expire =
 					    TIME_LEQ(dst->expire, time_second) ?
 						0 : dst->expire - time_second ;
+					dst->created =
+					    TIME_LEQ(time_second, dst->created) ?
+					        0 : time_second - dst->created;
 					bp += sizeof(ipfw_dyn_rule);
 				}
 			}

--- ipfw.8	1.150.2.4 2004/11/08 19:07:03
+++ ipfw.8	Fri Nov 26 18:59:20 2004
@@ -13,7 +13,7 @@
 .Cm add
 .Ar rule
 .Nm
-.Op Fl acdefnNStT
+.Op Fl acCdefnNStT
 .Brq Cm list | show
 .Op Ar rule | first-last ...
 .Nm
@@ -223,6 +223,10 @@ Implies
 When entering or showing rules, print them in compact form,
 i.e., without the optional "ip from any to any" string
 when this does not carry any additional information.
+.It Fl C
+When viewing dynamic firewall rules, print the number of
+seconds since the rule was created rather than the number
+of seconds until the rule expires.
 .It Fl d
 While listing, show dynamic rules in addition to static ones.
 .It Fl e


--- ipfw2.c	1.54.2.3 2004/09/17 14:49:08
+++ ipfw2.c	Fri Nov 26 18:57:04 2004
@@ -67,6 +67,7 @@ int
 		show_sets,		/* display rule sets */
 		test_only,		/* only check syntax */
 		comment_only,		/* only print action and comment */
+		show_created,		/* show creation time */
 		verbose;

 #define	IP_MASK_ALL	0xffffffff
@@ -1367,7 +1368,8 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwi
 	if (pcwidth>0 || bcwidth>0)
 	    printf(" %*llu %*llu (%ds)", pcwidth,
 		align_uint64(&d->pcnt), bcwidth,
-		align_uint64(&d->bcnt), d->expire);
+		align_uint64(&d->bcnt),
+		show_created ? d->created : d->expire);
 	switch (d->dyn_type) {
 	case O_LIMIT_PARENT:
 		printf(" PARENT %d", d->count);
@@ -3843,7 +3845,7 @@ ipfw_main(int oldac, char **oldav)
 	save_av = av;

 	optind = optreset = 0;
-	while ((ch = getopt(ac, av, "abcdefhnNqs:STtv")) != -1)
+	while ((ch = getopt(ac, av, "abcCdefhnNqs:STtv")) != -1)
 		switch (ch) {
 		case 'a':
 			do_acct = 1;
@@ -3906,7 +3908,9 @@ ipfw_main(int oldac, char **oldav)
 		case 'v': /* verbose */
 			verbose = 1;
 			break;
-
+		case 'C': /* created time */
+			show_created = 1;
+			break;
 		default:
 			free_args(save_ac, save_av);
 			return 1;




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?MDEHLPKNGKAHNMBLJOLKGEJPABAB.davids>