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