From owner-freebsd-hackers@FreeBSD.ORG Tue Sep 23 11:31:30 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2778616A4B3 for ; Tue, 23 Sep 2003 11:31:30 -0700 (PDT) Received: from xorpc.icir.org (xorpc.icir.org [192.150.187.68]) by mx1.FreeBSD.org (Postfix) with ESMTP id 45C0E44005 for ; Tue, 23 Sep 2003 11:31:29 -0700 (PDT) (envelope-from rizzo@xorpc.icir.org) Received: from xorpc.icir.org (localhost [127.0.0.1]) by xorpc.icir.org (8.12.9p1/8.12.3) with ESMTP id h8NIVSsd024814; Tue, 23 Sep 2003 11:31:29 -0700 (PDT) (envelope-from rizzo@xorpc.icir.org) Received: (from rizzo@localhost) by xorpc.icir.org (8.12.9p1/8.12.3/Submit) id h8NIVQjd024813; Tue, 23 Sep 2003 11:31:26 -0700 (PDT) (envelope-from rizzo) Date: Tue, 23 Sep 2003 11:31:26 -0700 From: Luigi Rizzo To: Matthew George Message-ID: <20030923113126.A24717@xorpc.icir.org> References: <20030922134531.A44366@xorpc.icir.org> <20030923122509.S87821@localhost> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <20030923122509.S87821@localhost>; from mdg@secureworks.net on Tue, Sep 23, 2003 at 12:28:07PM -0400 cc: freebsd-hackers@freebsd.org cc: Uwe Klann Subject: Re: IPFW2 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Sep 2003 18:31:30 -0000 On Tue, Sep 23, 2003 at 12:28:07PM -0400, Matthew George wrote: ... > > you can count the traffic with dynamic rules (but this does not go > > to the logfile), not sure what you mean by 'see the transfered data file' > > from ipf(5): > > LOGGING > When a packet is logged, with either the log action or option, the > headers of the packet are written to the ipl packet logging psuedo- > device. Immediately following the log keyword, the following qualifiers > may be used (in order): > > body indicates that the first 128 bytes of the packet contents will > be logged after the headers. > > I don't believe there is a comparable ipfw option ... no, there isn't. However the attached patch lets you run any bpf-based application on the packets which match an ipfw rule with 'log' specifier when net.inet.ip.fw.verbose=0, thus achieving a very similar if not a lot more powerful effect. Just use sysctl net.inet.ip.fw.verbose=0 ipfw add count log ... tcpdump -i ipfw0 ... cheers luigi Index: sys/netinet/ip_fw2.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v retrieving revision 1.6.2.16 diff -u -r1.6.2.16 ip_fw2.c --- sys/netinet/ip_fw2.c 17 Jul 2003 06:03:39 -0000 1.6.2.16 +++ sys/netinet/ip_fw2.c 22 Sep 2003 22:21:38 -0000 @@ -51,10 +51,12 @@ #include #include #include +#include /* for SIOC* */ #include #include #include #include +#include /* for BPF */ #include #include #include @@ -225,9 +227,14 @@ &dyn_short_lifetime, 0, "Lifetime of dyn. rules for other situations"); SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive, CTLFLAG_RW, &dyn_keepalive, 0, "Enable keepalives for dyn. rules"); +static int fw_bpf_info = 1; +SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, bpf_info, + CTLFLAG_RW, + &fw_bpf_info, 0, "Add info in mac hdr"); #endif /* SYSCTL_NODE */ +static struct ifnet ifn; /* dummy ifnet to attach to bpf */ static ip_fw_chk_t ipfw_chk; @@ -1812,6 +1819,44 @@ case O_LOG: if (fw_verbose) ipfw_log(f, hlen, args->eh, m, oif); + else if (ifn.if_bpf != NULL) { + /* + * Prepend a (readonly) header, fill it + * with the real MAC header, or a dummy + * one if not available. In this case + * (layer3 packets) also restore the + * byte ordering of some fields, and put + * them back after bpf_mtap. + * If requested, the first two bytes + * of the src mac are replaced by the + * rule number for userland filtering. + */ + struct m_hdr mh; + struct ether_header my_eh; + char *h; + + mh.mh_next = m; + mh.mh_len = ETHER_HDR_LEN; + mh.mh_data = (char *)&my_eh; + if (args->eh) /* layer2, complete */ + h = (char *)args->eh; + else { + h = "DDDDDDSSSSSS\x08\x00"; + ip->ip_off = ntohs(ip->ip_off); + ip->ip_len = ntohs(ip->ip_len); + } + bcopy(h, &my_eh, ETHER_HDR_LEN); + if (fw_bpf_info) { + mh.mh_data[0] = f->rulenum >> 8; + mh.mh_data[1] = f->rulenum & 0xff; + } + bpf_mtap(&ifn, (struct mbuf *)&mh); + if (args->eh == NULL) { + /* restore IP format */ + ip->ip_off = htons(ip->ip_off); + ip->ip_len = htons(ip->ip_len); + } + } match = 1; break; @@ -2767,11 +2833,34 @@ ipfw_timeout_h = timeout(ipfw_tick, NULL, dyn_keepalive_period*hz); } +static int +ipfw_ifnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) +{ + int error = 0; + + switch (cmd) { + default: + error = EINVAL; + break; + + case SIOCSIFADDR: + case SIOCGIFADDR: + case SIOCSIFFLAGS: + break; + } + return error; +} + static void ipfw_init(void) { struct ip_fw default_rule; + ifn.if_name = "ipfw"; + ifn.if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; + ifn.if_ioctl = ipfw_ifnet_ioctl; /* getaddr */ + ether_ifattach(&ifn, ETHER_BPF_SUPPORTED); + ip_fw_chk_ptr = ipfw_chk; ip_fw_ctl_ptr = ipfw_ctl; layer3_chain = NULL; @@ -2844,6 +2933,7 @@ err = EBUSY; #else s = splimp(); + ether_ifdetach(&ifn, 1 /* we want bpf */); untimeout(ipfw_tick, NULL, ipfw_timeout_h); ip_fw_chk_ptr = NULL; ip_fw_ctl_ptr = NULL;