Date: Tue, 23 Sep 2003 11:31:26 -0700 From: Luigi Rizzo <rizzo@icir.org> To: Matthew George <mdg@secureworks.net> Cc: Uwe Klann <u.klann@t-online.de> Subject: Re: IPFW2 Message-ID: <20030923113126.A24717@xorpc.icir.org> In-Reply-To: <20030923122509.S87821@localhost>; from mdg@secureworks.net on Tue, Sep 23, 2003 at 12:28:07PM -0400 References: <LIEAKECJDNPINKLJPFODIEPGDHAA.u.klann@t-online.de> <20030922134531.A44366@xorpc.icir.org> <20030923122509.S87821@localhost>
next in thread | previous in thread | raw e-mail | index | archive | help
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 <sys/proc.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/sockio.h> /* for SIOC* */ #include <sys/sysctl.h> #include <sys/syslog.h> #include <sys/ucred.h> #include <net/if.h> +#include <net/bpf.h> /* for BPF */ #include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030923113126.A24717>