Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jul 1999 15:54:55 -0400 (EDT)
From:      "Brian F. Feldman" <green@FreeBSD.org>
To:        Nate Williams <nate@mt.sri.com>
Cc:        Joe Greco <jgreco@ns.sol.net>, hackers@FreeBSD.org, freebsd-ipfw@FreeBSD.org
Subject:   Re: securelevel and ipfw zero
Message-ID:  <Pine.BSF.4.10.9907281552420.92555-100000@janus.syracuse.net>
In-Reply-To: <199907281937.NAA02547@mt.sri.com>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
I need help finishing it. The ipfw.8 manpage isn't quite fixed yet. When
someone will do that, it will be Ready :) But I've attached it!

 Brian Fundakowski Feldman      _ __ ___ ____  ___ ___ ___  
 green@FreeBSD.org                   _ __ ___ | _ ) __|   \ 
     FreeBSD: The Power to Serve!        _ __ | _ \._ \ |) |
       http://www.FreeBSD.org/              _ |___/___/___/ 


Index: src/sbin/ipfw/ipfw.8
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw.8,v
retrieving revision 1.54
diff -u -r1.54 ipfw.8
--- ipfw.8	1999/06/19 18:43:18	1.54
+++ ipfw.8	1999/07/28 19:35:31
@@ -50,6 +50,7 @@
 .Op Ar number
 .Ar action 
 .Op log
+.Op Ar logamount Ar number
 .Ar proto
 from
 .Ar src
Index: src/sbin/ipfw/ipfw.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw.c,v
retrieving revision 1.71
diff -u -r1.71 ipfw.c
--- ipfw.c	1999/06/19 18:43:15	1.71
+++ ipfw.c	1999/07/28 06:15:08
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
+#include <sys/sysctl.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 
@@ -247,8 +248,11 @@
 			errx(EX_OSERR, "impossible");
 	}
    
-	if (chain->fw_flg & IP_FW_F_PRN)
+	if (chain->fw_flg & IP_FW_F_PRN) {
 		printf(" log");
+		if (chain->fw_logamount)
+			printf(" logamount %d", chain->fw_logamount);
+	}
 
 	pe = getprotobynumber(chain->fw_prot);
 	if (pe)
@@ -599,12 +603,13 @@
 "    [pipe] list [number ...]\n"
 "    [pipe] show [number ...]\n"
 "    zero [number ...]\n"
+"    resetlog [number ...]\n"
 "    pipe number config [pipeconfig]\n"
 "  rule:  action proto src dst extras...\n"
 "    action:\n"
 "      {allow|permit|accept|pass|deny|drop|reject|unreach code|\n"
 "       reset|count|skipto num|divert port|tee port|fwd ip|\n"
-"       pipe num} [log]\n"
+"       pipe num} [log [logamount count]]\n"
 "    proto: {ip|tcp|udp|icmp|<number>}\n"
 "    src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
 "    dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
@@ -1164,6 +1169,18 @@
 	if (ac && !strncmp(*av,"log",strlen(*av))) {
 		rule.fw_flg |= IP_FW_F_PRN; av++; ac--;
 	}
+	if (ac && !strncmp(*av,"logamount",strlen(*av))) {
+		if (!(rule.fw_flg & IP_FW_F_PRN))
+			show_usage("``logamount'' not valid without ``log''");
+		ac--; av++;
+		if (!ac)
+			show_usage("``logamount'' requires argument");
+		rule.fw_logamount = atoi(*av);
+		if (rule.fw_logamount <= 0)
+			show_usage("``logamount'' argument must be greater "
+			    "than 0");
+		ac--; av++;
+	}
 
 	/* protocol */
 	if (ac == 0)
@@ -1385,7 +1402,18 @@
 		if (rule.fw_nports)
 			show_usage("can't mix 'frag' and port specifications");
 	}
-
+	if (rule.fw_flg & IP_FW_F_PRN) {
+		if (!rule.fw_logamount) {
+			size_t len = sizeof(int);
+
+			if (sysctlbyname("net.inet.ip.fw.verbose_limit",
+			    &rule.fw_logamount, &len, NULL, 0) == -1)
+				errx(1, "sysctlbyname(\"%s\")",
+				    "net.inet.ip.fw.verbose_limit");
+		}
+		rule.fw_loghighest = rule.fw_logamount;
+	}
+	
 	if (!do_quiet)
 		show_ipfw(&rule, 10, 10);
 	i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
@@ -1432,6 +1460,45 @@
 	}
 }
 
+static void
+resetlog (ac, av)
+	int ac;
+	char **av;
+{
+	av++; ac--;
+
+	if (!ac) {
+		/* clear all entries */
+		if (setsockopt(s,IPPROTO_IP,IP_FW_RESETLOG,NULL,0)<0)
+			err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_RESETLOG");
+		if (!do_quiet)
+			printf("Logging counts reset.\n");
+	} else {
+		struct ip_fw rule;
+		int failed = EX_OK;
+
+		memset(&rule, 0, sizeof rule);
+		while (ac) {
+			/* Rule number */
+			if (isdigit(**av)) {
+				rule.fw_number = atoi(*av); av++; ac--;
+				if (setsockopt(s, IPPROTO_IP,
+				    IP_FW_RESETLOG, &rule, sizeof rule)) {
+					warn("rule %u: setsockopt(%s)", rule.fw_number,
+						 "IP_FW_RESETLOG");
+					failed = EX_UNAVAILABLE;
+				}
+				else if (!do_quiet)
+					printf("Entry %d logging count reset\n",
+					    rule.fw_number);
+			} else
+				show_usage("invalid rule number ``%s''", *av);
+		}
+		if (failed != EX_OK)
+			exit(failed);
+	}
+}
+
 static int
 ipfw_main(ac,av)
 	int 	ac;
@@ -1527,6 +1594,8 @@
 		}
 	} else if (!strncmp(*av, "zero", strlen(*av))) {
 		zero(ac,av);
+	} else if (!strncmp(*av, "resetlog", strlen(*av))) {
+		resetlog(ac,av);
 	} else if (!strncmp(*av, "print", strlen(*av))) {
 		list(--ac,++av);
 	} else if (!strncmp(*av, "list", strlen(*av))) {
Index: src/sys/netinet/ip_fw.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.c,v
retrieving revision 1.114
diff -u -r1.114 ip_fw.c
--- ip_fw.c	1999/06/19 18:43:28	1.114
+++ ip_fw.c	1999/07/28 06:29:07
@@ -106,6 +106,7 @@
 static int	add_entry __P((struct ip_fw_head *chainptr, struct ip_fw *frwl));
 static int	del_entry __P((struct ip_fw_head *chainptr, u_short number));
 static int	zero_entry __P((struct ip_fw *));
+static int	resetlog_entry __P((struct ip_fw *));
 static int	check_ipfw_struct __P((struct ip_fw *m));
 static __inline int
 		iface_match __P((struct ifnet *ifp, union ip_fw_if *ifu,
@@ -184,8 +185,8 @@
 
 	/* check for matching type in the bitmap */
 	if (type < IP_FW_ICMPTYPES_MAX &&
-		(f->fw_uar.fw_icmptypes[type / (sizeof(unsigned) * 8)] & 
-		(1U << (type % (8 * sizeof(unsigned))))))
+	    (f->fw_uar.fw_icmptypes[type / (sizeof(unsigned) * NBBY)] & 
+	     (1U << (type % (sizeof(unsigned) * NBBY)))))
 		return(1);
 
 	return(0); /* no match */
@@ -302,14 +303,15 @@
 	struct ifnet *rif, struct ifnet *oif)
 {
     if (ip) {
+	struct tcphdr *const tcp = (struct tcphdr *)((u_int32_t *)ip+ip->ip_hl);
+	struct udphdr *const udp = (struct udphdr *)((u_int32_t *)ip+ip->ip_hl);
+	struct icmp *const icmp = (struct icmp *)((u_int32_t *)ip+ip->ip_hl);
 	static u_int64_t counter;
-	struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl);
-	struct udphdr *const udp = (struct udphdr *) ((u_int32_t *) ip+ ip->ip_hl);
-	struct icmp *const icmp = (struct icmp *) ((u_int32_t *) ip + ip->ip_hl);
-	int count;
+	u_int64_t count;
 
 	count = f ? f->fw_pcnt : ++counter;
-	if (fw_verbose_limit != 0 && count > fw_verbose_limit)
+	if ((f == NULL && fw_verbose_limit != 0 && count > fw_verbose_limit) ||
+	    (f && f->fw_logamount != 0 && count > f->fw_loghighest))
 		return;
 
 	/* Print command name */
@@ -406,12 +408,13 @@
 		printf(" out via %s%d", oif->if_name, oif->if_unit);
 	else if (rif)
 		printf(" in via %s%d", rif->if_name, rif->if_unit);
-	if ((ip->ip_off & IP_OFFMASK)) 
-		printf(" Fragment = %d",ip->ip_off & IP_OFFMASK);
+	if (ip->ip_off & IP_OFFMASK)
+		printf(" Fragment = %d", ip->ip_off & IP_OFFMASK);
 	printf("\n");
-	if (fw_verbose_limit != 0 && count == fw_verbose_limit)
-		printf("ipfw: limit reached on rule #%d\n",
-		f ? f->fw_number : -1);
+	if ((f ? f->fw_logamount != 0 : 1) &&
+	    count == (f ? f->fw_loghighest : fw_verbose_limit))
+		printf("ipfw: limit %d reached on rule #%d\n",
+		f ? f->fw_logamount : fw_verbose_limit, f ? f->fw_number : -1);
     }
 }
 
@@ -1108,6 +1111,55 @@
 }
 
 static int
+resetlog_entry(struct ip_fw *frwl)
+{
+	struct ip_fw_chain *fcp;
+	int s, cleared;
+
+	if (frwl == 0) {
+		s = splnet();
+		for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain))
+			fcp->rule->fw_loghighest = fcp->rule->fw_pcnt +
+			    fcp->rule->fw_logamount;
+		splx(s);
+	}
+	else {
+		cleared = 0;
+
+		/*
+		 *	It's possible to insert multiple chain entries with the
+		 *	same number, so we don't stop after finding the first
+		 *	match if zeroing a specific entry.
+		 */
+		for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain))
+			if (frwl->fw_number == fcp->rule->fw_number) {
+				s = splnet();
+				while (fcp && frwl->fw_number == fcp->rule->fw_number) {
+					fcp->rule->fw_loghighest =
+					    fcp->rule->fw_pcnt +
+					    fcp->rule->fw_logamount;
+					fcp = LIST_NEXT(fcp, chain);
+				}
+				splx(s);
+				cleared = 1;
+				break;
+			}
+		if (!cleared)	/* we didn't find any matching rules */
+			return (EINVAL);
+	}
+
+	if (fw_verbose) {
+		if (frwl)
+			printf("ipfw: Entry %d logging count reset.\n",
+			    frwl->fw_number);
+		else
+			printf("ipfw: All logging counts cleared.\n");
+	}
+
+	return (0);
+}
+
+static int
 check_ipfw_struct(struct ip_fw *frwl)
 {
 	/* Check for invalid flag bits */
@@ -1320,6 +1372,17 @@
 		}
 		break;
 
+	case IP_FW_RESETLOG:
+		if (sopt->sopt_val != 0) {
+			error = sooptcopyin(sopt, &frwl, sizeof frwl,
+					    sizeof frwl);
+			if (error || (error = resetlog_entry(&frwl)))
+				break;
+		} else {
+			error = resetlog_entry(0);
+		}
+		break;
+
 	default:
 		printf("ip_fw_ctl invalid option %d\n", sopt->sopt_name);
 		error = EINVAL ;
@@ -1373,7 +1436,7 @@
 	if (fw_verbose_limit == 0)
 		printf("unlimited logging\n");
 	else
-		printf("logging limited to %d packets/entry\n",
+		printf("logging limited to %d packets/entry by default\n",
 		    fw_verbose_limit);
 #endif
 }
Index: src/sys/netinet/ip_fw.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.38
diff -u -r1.38 ip_fw.h
--- ip_fw.h	1999/06/19 18:43:30	1.38
+++ ip_fw.h	1999/07/28 05:08:07
@@ -75,14 +75,18 @@
 	struct sockaddr_in fu_fwd_ip;
     } fw_un;
     u_char fw_prot;			/* IP protocol */
-    u_char fw_nports;			/* N'of src ports and # of dst ports */
-					/* in ports array (dst ports follow */
-					/* src ports; max of 10 ports in all; */
-					/* count of 0 means match all ports) */
-    void *pipe_ptr;                    /* Pipe ptr in case of dummynet pipe */
-    void *next_rule_ptr ;              /* next rule in case of match */
+    u_char fw_nports;			/*
+					 * N'of src ports and # of dst ports
+					 * in ports array (dst ports follow
+					 * src ports; max of 10 ports in all;
+					 * count of 0 means match all ports)
+					 */
+    void *pipe_ptr;			/* pipe ptr in case of dummynet pipe */
+    void *next_rule_ptr;		/* next rule in case of match */
     uid_t fw_uid;			/* uid to match */
     gid_t fw_gid;			/* gid to match */
+    int fw_logamount;			/* amount to log */
+    u_int64_t fw_loghighest;		/* highest number packet to log */
 };
 
 #define IP_FW_GETNSRCP(rule)		((rule)->fw_nports & 0x0f)
Index: src/sys/netinet/in.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.h,v
retrieving revision 1.42
diff -u -r1.42 in.h
--- in.h	1999/05/08 14:28:52	1.42
+++ in.h	1999/07/28 05:46:20
@@ -322,6 +322,7 @@
 #define IP_FW_FLUSH   		52   /* flush firewall rule chain */
 #define IP_FW_ZERO    		53   /* clear single/all firewall counter(s) */
 #define IP_FW_GET     		54   /* get entire firewall rule chain */
+#define IP_FW_RESETLOG		55   /* reset logging counters */
 
 #define	IP_DUMMYNET_CONFIGURE	60   /* add/configure a dummynet pipe */
 #define	IP_DUMMYNET_DEL		61   /* delete a dummynet pipe from chain */
Index: src/sys/netinet/raw_ip.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.59
diff -u -r1.59 raw_ip.c
--- raw_ip.c	1999/05/03 23:57:30	1.59
+++ raw_ip.c	1999/07/28 06:07:59
@@ -293,6 +293,7 @@
 		case IP_FW_DEL:
 		case IP_FW_FLUSH:
 		case IP_FW_ZERO:
+		case IP_FW_RESETLOG:
 			if (ip_fw_ctl_ptr == 0)
 				error = ENOPROTOOPT;
 			else



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ipfw" in the body of the message




Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.9907281552420.92555-100000>