Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net add BIOC{G, S}FEEDBACK which allows one to receive in...



details:   https://anonhg.NetBSD.org/src/rev/9ac1ee37d782
branches:  trunk
changeset: 752986:9ac1ee37d782
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Mar 13 20:38:48 2010 +0000

description:
add BIOC{G,S}FEEDBACK which allows one to receive injected outgoing packets
via bpf.

diffstat:

 sys/net/bpf.c     |  54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 sys/net/bpf.h     |   5 ++++-
 sys/net/bpfdesc.h |   3 ++-
 3 files changed, 56 insertions(+), 6 deletions(-)

diffs (162 lines):

diff -r 6745fd8ef972 -r 9ac1ee37d782 sys/net/bpf.c
--- a/sys/net/bpf.c     Sat Mar 13 19:49:50 2010 +0000
+++ b/sys/net/bpf.c     Sat Mar 13 20:38:48 2010 +0000
@@ -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;
diff -r 6745fd8ef972 -r 9ac1ee37d782 sys/net/bpf.h
--- a/sys/net/bpf.h     Sat Mar 13 19:49:50 2010 +0000
+++ b/sys/net/bpf.h     Sat Mar 13 20:38:48 2010 +0000
@@ -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
diff -r 6745fd8ef972 -r 9ac1ee37d782 sys/net/bpfdesc.h
--- a/sys/net/bpfdesc.h Sat Mar 13 19:49:50 2010 +0000
+++ b/sys/net/bpfdesc.h Sat Mar 13 20:38:48 2010 +0000
@@ -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



Home | Main Index | Thread Index | Old Index