Date: Tue, 15 Dec 2009 00:53:07 +0100 From: Luigi Rizzo <rizzo@iet.unipi.it> To: current@freebsd.org Subject: [PATCH] ipfw logging through tcpdump ? Message-ID: <20091214235307.GA5345@onelab2.iet.unipi.it>
next in thread | raw e-mail | index | archive | help
The following ipfw patch (which i wrote back in 2001/2002) makes ipfw logging possible through tcpdump -- it works by passing to the fake device 'ipfw0' all packets matching rules marked 'log' . The use is very simple -- to test it just do ipfw add 100 count log ip from any to any and then tcpdump -ni ipfw0 will show all matching traffic. I think this is a quite convenient and flexible option, so if there are no objections I plan to commit it to head. cheers luigi Index: ../head/sys/netinet/ipfw/ip_fw2.c =================================================================== --- ../head/sys/netinet/ipfw/ip_fw2.c (revision 200551) +++ ../head/sys/netinet/ipfw/ip_fw2.c (working copy) @@ -65,6 +65,8 @@ #include <sys/ucred.h> #include <net/ethernet.h> /* for ETHERTYPE_IP */ #include <net/if.h> +#include <net/if_types.h> /* for IFT_ETHER */ +#include <net/bpf.h> /* for BPF */ #include <net/radix.h> #include <net/route.h> #include <net/pf_mtag.h> @@ -338,6 +340,15 @@ "Enable keepalives for dyn. rules"); #endif /* SYSCTL_NODE */ +#ifdef DEV_IPFW +static struct ifnet *ifn; /* hook to attach to bpf */ +static int +ipfw_ifnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) +{ + return EINVAL; +} +#endif + /* * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T * Other macros just cast void * into the appropriate type @@ -3056,6 +3067,29 @@ if (V_fw_verbose) ipfw_log(f, hlen, args, m, oif, offset, tablearg, ip); +#ifdef DEV_IPFW + else if (ifn && ifn->if_bpf != NULL) { + /* This kludge is OK; BPF treats + *the "mbuf" as read-only */ + struct m_hdr mh; + mh.mh_next = m; + mh.mh_len = ETHER_HDR_LEN; + if (args->eh) /* layer2, complete */ + mh.mh_data = (char *)args->eh; + else { + /* fake header and restore wire format*/ + mh.mh_data = "DDDDDDSSSSSS\x08\x00"; + ip->ip_off = ntohs(ip->ip_off); + ip->ip_len = ntohs(ip->ip_len); + } + 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); + } + } +#endif /* DEV_IPFW */ match = 1; break; @@ -4830,6 +4864,19 @@ printf("limited to %d packets/entry by default\n", V_verbose_limit); +#ifdef DEV_IPFW /** bpf code **/ + ifn = if_alloc(IFT_ETHER); + if_initname(ifn, "ipfw", 0); + ifn->if_mtu = 65536; + ifn->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; + ifn->if_ioctl = ipfw_ifnet_ioctl; /* getaddr */ + ifn->if_addrlen = 6; + ifn->if_hdrlen = 14; + if_attach(ifn); + ifn->if_baudrate = IF_Mbps(10); + bpfattach(ifn, DLT_EN10MB, 14); +#endif /** end bpf code **/ + return (error); } @@ -4840,6 +4887,11 @@ ipfw_destroy(void) { +#ifdef DEV_IPFW + ether_ifdetach(ifn); + if_free(ifn); + ifn = NULL; +#endif uma_zdestroy(ipfw_dyn_rule_zone); IPFW_DYN_LOCK_DESTROY(); printf("IP firewall unloaded\n");
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091214235307.GA5345>