Module Name: src Committed By: christos Date: Sat Mar 13 20:38:48 UTC 2010
Modified Files: src/sys/net: bpf.c bpf.h bpfdesc.h Log Message: add BIOC{G,S}FEEDBACK which allows one to receive injected outgoing packets via bpf. To generate a diff of this commit: cvs rdiff -u -r1.155 -r1.156 src/sys/net/bpf.c cvs rdiff -u -r1.53 -r1.54 src/sys/net/bpf.h cvs rdiff -u -r1.31 -r1.32 src/sys/net/bpfdesc.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/bpf.c diff -u src/sys/net/bpf.c:1.155 src/sys/net/bpf.c:1.156 --- src/sys/net/bpf.c:1.155 Mon Jan 25 20:06:23 2010 +++ src/sys/net/bpf.c Sat Mar 13 15:38:48 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: bpf.c,v 1.155 2010/01/26 01:06:23 pooka Exp $ */ +/* $NetBSD: bpf.c,v 1.156 2010/03/13 20:38:48 christos Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.155 2010/01/26 01:06:23 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.156 2010/03/13 20:38:48 christos Exp $"); #if defined(_KERNEL_OPT) #include "opt_bpf.h" @@ -407,6 +407,7 @@ d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK|M_ZERO); d->bd_bufsize = bpf_bufsize; d->bd_seesent = 1; + d->bd_feedback = 0; d->bd_pid = l->l_proc->p_pid; getnanotime(&d->bd_btime); d->bd_atime = d->bd_mtime = d->bd_btime; @@ -622,7 +623,7 @@ { struct bpf_d *d = fp->f_data; struct ifnet *ifp; - struct mbuf *m; + struct mbuf *m, *mc; int error, s; static struct sockaddr_storage dst; @@ -659,8 +660,24 @@ if (d->bd_hdrcmplt) dst.ss_family = pseudo_AF_HDRCMPLT; + if (d->bd_feedback) { + mc = m_dup(m, 0, M_COPYALL, M_NOWAIT); + if (mc != NULL) + mc->m_pkthdr.rcvif = ifp; + /* Set M_PROMISC for outgoing packets to be discarded. */ + if (1 /*d->bd_direction == BPF_D_INOUT*/) + m->m_flags |= M_PROMISC; + } else + mc = NULL; + s = splsoftnet(); error = (*ifp->if_output)(ifp, m, (struct sockaddr *) &dst, NULL); + + if (mc != NULL) { + if (error == 0) + (*ifp->if_input)(ifp, mc); + } else + m_freem(mc); splx(s); KERNEL_UNLOCK_ONE(NULL); /* @@ -704,6 +721,10 @@ * BIOCVERSION Get filter language version. * BIOCGHDRCMPLT Get "header already complete" flag. * BIOCSHDRCMPLT Set "header already complete" flag. + * BIOCSFEEDBACK Set packet feedback mode. + * BIOCGFEEDBACK Get packet feedback mode. + * BIOCGSEESENT Get "see sent packets" mode. + * BIOCSSEESENT Set "see sent packets" mode. */ /* ARGSUSED */ static int @@ -975,6 +996,20 @@ d->bd_seesent = *(u_int *)addr; break; + /* + * Set "feed packets from bpf back to input" mode + */ + case BIOCSFEEDBACK: + d->bd_feedback = *(u_int *)addr; + break; + + /* + * Get "feed packets from bpf back to input" mode + */ + case BIOCGFEEDBACK: + *(u_int *)addr = d->bd_feedback; + break; + case FIONBIO: /* Non-blocking I/O */ /* * No need to do anything special as we use IO_NDELAY in @@ -1356,6 +1391,12 @@ u_int pktlen; struct mbuf mb; + /* Skip outgoing duplicate packets. */ + if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { + m->m_flags &= ~M_PROMISC; + return; + } + pktlen = m_length(m) + dlen; /* @@ -1381,6 +1422,12 @@ u_int pktlen, buflen; void *marg; + /* Skip outgoing duplicate packets. */ + if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { + m->m_flags &= ~M_PROMISC; + return; + } + pktlen = m_length(m); if (pktlen == m->m_len) { @@ -1388,7 +1435,6 @@ marg = mtod(m, void *); buflen = pktlen; } else { -/*###1299 [cc] warning: assignment from incompatible pointer type%%%*/ cpfn = bpf_mcpy; marg = m; buflen = 0; Index: src/sys/net/bpf.h diff -u src/sys/net/bpf.h:1.53 src/sys/net/bpf.h:1.54 --- src/sys/net/bpf.h:1.53 Mon Jan 25 17:18:17 2010 +++ src/sys/net/bpf.h Sat Mar 13 15:38:48 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: bpf.h,v 1.53 2010/01/25 22:18:17 pooka Exp $ */ +/* $NetBSD: bpf.h,v 1.54 2010/03/13 20:38:48 christos Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -139,6 +139,9 @@ #define BIOCSSEESENT _IOW('B',121, u_int) #define BIOCSRTIMEOUT _IOW('B',122, struct timeval) #define BIOCGRTIMEOUT _IOR('B',123, struct timeval) +#define BIOCGFEEDBACK _IOR('B',124, u_int) +#define BIOCSFEEDBACK _IOW('B',125, u_int) +#define BIOCFEEDBACK BIOCSFEEDBACK /* FreeBSD name */ /* * Structure prepended to each packet. This is "wire" format, so we Index: src/sys/net/bpfdesc.h diff -u src/sys/net/bpfdesc.h:1.31 src/sys/net/bpfdesc.h:1.32 --- src/sys/net/bpfdesc.h:1.31 Thu Jan 21 15:51:31 2010 +++ src/sys/net/bpfdesc.h Sat Mar 13 15:38:48 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: bpfdesc.h,v 1.31 2010/01/21 20:51:31 dyoung Exp $ */ +/* $NetBSD: bpfdesc.h,v 1.32 2010/03/13 20:38:48 christos Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -79,6 +79,7 @@ u_char bd_immediate; /* true to return on packet arrival */ int bd_hdrcmplt; /* false to fill in src lladdr */ int bd_seesent; /* true if bpf should see sent packets */ + int bd_feedback; /* true to feed back sent packets */ int bd_async; /* non-zero if packet reception should generate signal */ pid_t bd_pgid; /* process or group id for signal */ #if BSD < 199103