From owner-freebsd-hackers Wed Jul 28 12:57:30 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from janus.syracuse.net (janus.syracuse.net [205.232.47.15]) by hub.freebsd.org (Postfix) with ESMTP id B05D015033; Wed, 28 Jul 1999 12:57:19 -0700 (PDT) (envelope-from green@FreeBSD.org) Received: from localhost (green@localhost) by janus.syracuse.net (8.9.2/8.8.7) with ESMTP id PAA93305; Wed, 28 Jul 1999 15:54:55 -0400 (EDT) X-Authentication-Warning: janus.syracuse.net: green owned process doing -bs Date: Wed, 28 Jul 1999 15:54:55 -0400 (EDT) From: "Brian F. Feldman" X-Sender: green@janus.syracuse.net To: Nate Williams Cc: Joe Greco , hackers@FreeBSD.org, freebsd-ipfw@FreeBSD.org Subject: Re: securelevel and ipfw zero In-Reply-To: <199907281937.NAA02547@mt.sri.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include +#include #include #include @@ -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|}\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-hackers" in the body of the message