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

Reply via email to