diff options
| author | Brian Feldman <green@FreeBSD.org> | 1999-08-01 16:57:24 +0000 |
|---|---|---|
| committer | Brian Feldman <green@FreeBSD.org> | 1999-08-01 16:57:24 +0000 |
| commit | 0b6c1a832d8c2306ebb95fa4f397abdb058dc931 (patch) | |
| tree | e08ad2be18bc729c7d4c181664743ce6c1ed72f2 /sys/netinet/ip_fw.c | |
| parent | 6e7b8c218d50da7a512bf5a811a1305edb4cd136 (diff) | |
Notes
Diffstat (limited to 'sys/netinet/ip_fw.c')
| -rw-r--r-- | sys/netinet/ip_fw.c | 89 |
1 files changed, 80 insertions, 9 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index a9e82886f2ba..5543bdf86c57 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 } |
