summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>1999-08-01 16:57:24 +0000
committergreen <green@FreeBSD.org>1999-08-01 16:57:24 +0000
commitd848a791d143dcd43bbfd4243df4fe61c62fac41 (patch)
tree02d5b553f5f87af777c6d66d6b2b25611e79109b /sys
parent7263583ccb568e6d5e6e6d32d6e126a50ea4229d (diff)
downloadFreeBSD-src-d848a791d143dcd43bbfd4243df4fe61c62fac41.zip
FreeBSD-src-d848a791d143dcd43bbfd4243df4fe61c62fac41.tar.gz
Make ipfw's logging more dynamic. Now, log will use the default limit
_or_ you may specify "log logamount number" to set logging specifically the rule. In addition, "ipfw resetlog" has been added, which will reset the logging counters on any/all rule(s). ipfw resetlog does not affect the packet/byte counters (as ipfw reset does), and is the only "set" command that can be run at securelevel >= 3. This should address complaints about not being able to set logging amounts, not being able to restart logging at a high securelevel, and not being able to just reset logging without resetting all of the counters in a rule.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/in.h3
-rw-r--r--sys/netinet/ip_fw.c89
-rw-r--r--sys/netinet/ip_fw.h4
-rw-r--r--sys/netinet/raw_ip.c3
4 files changed, 87 insertions, 12 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 1eebb9a..1838def 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)in.h 8.3 (Berkeley) 1/3/94
- * $Id: in.h,v 1.41 1999/05/04 16:20:29 luigi Exp $
+ * $Id: in.h,v 1.42 1999/05/08 14:28:52 peter Exp $
*/
#ifndef _NETINET_IN_H_
@@ -322,6 +322,7 @@ struct ip_opts {
#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 */
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index a9e8288..5543bdf 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -12,7 +12,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.114 1999/06/19 18:43:28 green Exp $
+ * $Id: ip_fw.c,v 1.115 1999/07/28 22:27:27 green Exp $
*/
/*
@@ -106,6 +106,7 @@ SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW,
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,
@@ -306,10 +307,11 @@ ipfw_report(struct ip_fw *f, struct ip *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);
- 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 */
@@ -409,9 +411,11 @@ ipfw_report(struct ip_fw *f, struct ip *ip,
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);
}
}
@@ -1069,6 +1073,7 @@ zero_entry(struct ip_fw *frwl)
s = splnet();
for (fcp = LIST_FIRST(&ip_fw_chain); fcp; fcp = LIST_NEXT(fcp, chain)) {
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
+ fcp->rule->fw_loghighest = fcp->rule->fw_logamount;
fcp->rule->timestamp = 0;
}
splx(s);
@@ -1086,6 +1091,8 @@ zero_entry(struct ip_fw *frwl)
s = splnet();
while (fcp && frwl->fw_number == fcp->rule->fw_number) {
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
+ fcp->rule->fw_loghighest =
+ fcp->rule->fw_logamount;
fcp->rule->timestamp = 0;
fcp = LIST_NEXT(fcp, chain);
}
@@ -1108,6 +1115,55 @@ zero_entry(struct ip_fw *frwl)
}
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 */
@@ -1241,8 +1297,12 @@ ip_fw_ctl(struct sockopt *sopt)
struct ip_fw_chain *fcp;
struct ip_fw frwl;
- /* Disallow sets in really-really secure mode. */
- if (sopt->sopt_dir == SOPT_SET && securelevel >= 3)
+ /*
+ * Disallow sets in really-really secure mode, but still allow
+ * the logging counters to be reset.
+ */
+ if (sopt->sopt_dir == SOPT_SET && securelevel >= 3 &&
+ sopt->sopt_name != IP_FW_RESETLOG)
return (EPERM);
error = 0;
@@ -1320,6 +1380,17 @@ ip_fw_ctl(struct sockopt *sopt)
}
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 +1444,7 @@ ip_fw_init(void)
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
}
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index d858040..958eb67 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.h,v 1.38 1999/06/19 18:43:30 green Exp $
+ * $Id: ip_fw.h,v 1.39 1999/07/28 22:22:57 green Exp $
*/
#ifndef _IP_FW_H
@@ -85,6 +85,8 @@ struct ip_fw {
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)
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index f94cc09..d8117dd 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
- * $Id: raw_ip.c,v 1.58 1999/04/27 11:17:36 phk Exp $
+ * $Id: raw_ip.c,v 1.59 1999/05/03 23:57:30 billf Exp $
*/
#include <sys/param.h>
@@ -293,6 +293,7 @@ rip_ctloutput(so, sopt)
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
OpenPOWER on IntegriCloud