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 _ __ ___ ____ ___ ___ ___
[EMAIL PROTECTED] _ __ ___ | _ ) __| \
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 [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message