Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Dec 2009 00:23:45 -0500
From:      David Horn <dhorn2000@gmail.com>
To:        Luigi Rizzo <rizzo@iet.unipi.it>
Cc:        current@freebsd.org
Subject:   Re: [PATCH] ipfw logging through tcpdump ?
Message-ID:  <25ff90d60912142123o661097c1k1b42eb292efd8acf@mail.gmail.com>
In-Reply-To: <20091214235307.GA5345@onelab2.iet.unipi.it>
References:  <20091214235307.GA5345@onelab2.iet.unipi.it>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Dec 14, 2009 at 6:53 PM, Luigi Rizzo <rizzo@iet.unipi.it> wrote:
> 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
>
> =A0 =A0 =A0 =A0ipfw add 100 count log ip from any to any
>
> and then
>
> =A0 =A0 =A0 =A0tcpdump -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.
>
> =A0 =A0 =A0 =A0cheers
> =A0 =A0 =A0 =A0luigi
>
> Index: ../head/sys/netinet/ipfw/ip_fw2.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- ../head/sys/netinet/ipfw/ip_fw2.c =A0 (revision 200551)
> +++ ../head/sys/netinet/ipfw/ip_fw2.c =A0 (working copy)
> @@ -65,6 +65,8 @@
> =A0#include <sys/ucred.h>
> =A0#include <net/ethernet.h> /* for ETHERTYPE_IP */
> =A0#include <net/if.h>
> +#include <net/if_types.h> =A0 =A0 =A0/* for IFT_ETHER */
> +#include <net/bpf.h> =A0 =A0 =A0 =A0 =A0 /* for BPF */
> =A0#include <net/radix.h>
> =A0#include <net/route.h>
> =A0#include <net/pf_mtag.h>
> @@ -338,6 +340,15 @@
> =A0 =A0 "Enable keepalives for dyn. rules");
> =A0#endif /* SYSCTL_NODE */
>
> +#ifdef DEV_IPFW
> +static struct ifnet *ifn; =A0 =A0 =A0/* hook to attach to bpf */
> +static int
> +ipfw_ifnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
> +{
> + =A0 =A0 =A0 return EINVAL;
> +}
> +#endif
> +
> =A0/*
> =A0* L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
> =A0* Other macros just cast void * into the appropriate type
> @@ -3056,6 +3067,29 @@
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (V_fw_v=
erbose)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0ipfw_log(f, hlen, args, m,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0oif, offset, tablearg, ip);
> +#ifdef DEV_IPFW
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else if (if=
n && ifn->if_bpf !=3D NULL) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* =
This kludge is OK; BPF treats
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
*the "mbuf" as read-only */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 str=
uct m_hdr mh;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mh.=
mh_next =3D m;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mh.=
mh_len =3D ETHER_HDR_LEN;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if =
(args->eh) =A0 =A0 =A0 /* layer2, complete */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 mh.mh_data =3D (char *)args->eh;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 els=
e {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 /* fake header and restore wire format*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 mh.mh_data =3D "DDDDDDSSSSSS\x08\x00";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 ip->ip_off =3D ntohs(ip->ip_off);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 ip->ip_len =3D ntohs(ip->ip_len);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 BPF=
_MTAP(ifn, (struct mbuf *)&mh);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if =
(args->eh =3D=3D NULL) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 /* restore IP format */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 ip->ip_off =3D htons(ip->ip_off);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 ip->ip_len =3D htons(ip->ip_len);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +#endif /* DEV_IPFW */
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0match =3D =
1;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
>
> @@ -4830,6 +4864,19 @@
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printf("limited to %d packets/entry by def=
ault\n",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0V_verbose_limit);
>
> +#ifdef DEV_IPFW =A0 =A0 =A0 =A0/** bpf code **/
> + =A0 =A0 =A0 ifn =3D if_alloc(IFT_ETHER);
> + =A0 =A0 =A0 if_initname(ifn, "ipfw", 0);
> + =A0 =A0 =A0 ifn->if_mtu =3D 65536;
> + =A0 =A0 =A0 ifn->if_flags =3D IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
> + =A0 =A0 =A0 ifn->if_ioctl =3D ipfw_ifnet_ioctl; =A0 =A0 =A0 =A0/* getad=
dr */
> + =A0 =A0 =A0 ifn->if_addrlen =3D 6;
> + =A0 =A0 =A0 ifn->if_hdrlen =3D 14;
> + =A0 =A0 =A0 if_attach(ifn);
> + =A0 =A0 =A0 ifn->if_baudrate =3D IF_Mbps(10);
> + =A0 =A0 =A0 bpfattach(ifn, DLT_EN10MB, 14);
> +#endif /** end bpf code **/
> +
> =A0 =A0 =A0 =A0return (error);
> =A0}
>
> @@ -4840,6 +4887,11 @@
> =A0ipfw_destroy(void)
> =A0{
>
> +#ifdef DEV_IPFW
> + =A0 =A0 =A0 ether_ifdetach(ifn);
> + =A0 =A0 =A0 if_free(ifn);
> + =A0 =A0 =A0 ifn =3D NULL;
> +#endif
> =A0 =A0 =A0 =A0uma_zdestroy(ipfw_dyn_rule_zone);
> =A0 =A0 =A0 =A0IPFW_DYN_LOCK_DESTROY();
> =A0 =A0 =A0 =A0printf("IP firewall unloaded\n");

Code works well for me with latest current r200562, although a bit of
extra fuzz factor was needed for the patch to apply cleanly.

My only comment is that I would prefer a tunable or sysctl to having
to recompile with CFLAGS+=3D -DDEV_IPFW added to the ipfw module
Makefile.

Very useful code.

---Dave Horn



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?25ff90d60912142123o661097c1k1b42eb292efd8acf>