> I can successfully write BPF packets up to 1500 bytes in size (1496 IP 
> bytes without the address family integer).  Writes larger than this 
> return EMSGSIZE.

http://lists.freebsd.org/pipermail/freebsd-net/2005-May/007371.html

Just for the record, the patch below fixes this on 4.11; the same
problem exists in HEAD today.  I'm pondering making an effort to add
write support to all interface types.  I would do this by adding an
extra parameter to bpf_if that specifies the size of the 'link layer'
it expects to encounter when bpfwrite is called.

struct bpf_if {
        LIST_ENTRY(bpf_if)      bif_next;       /* list of all interfaces */
        LIST_HEAD(, bpf_d)      bif_dlist;      /* descriptor list */
        struct bpf_if **bif_driverp;    /* pointer into softc */
        u_int bif_dlt;                  /* link layer type */
-       u_int bif_hdrlen;               /* length of header (with padding) */
+       u_int bif_hdrlen_rx;            /* link header passed to bpf reader */
+       u_int bif_hdrlen_tx;            /* link header passed by bpf writer */
        struct ifnet *bif_ifp;          /* corresponding interface */
        struct mtx      bif_mtx;        /* mutex for interface */
};

If I was to pursue this, would someone on this list consider committing the
work to current?

Index: bpf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bpf.c,v
retrieving revision 1.59.2.13
diff -u -p -r1.59.2.13 bpf.c
--- bpf.c       21 Aug 2003 23:50:54 -0000      1.59.2.13
+++ bpf.c       6 Jun 2005 07:54:12 -0000
@@ -120,7 +120,7 @@ static void bpf_detachd __P((struct bpf_
 static void    bpf_freed __P((struct bpf_d *));
 static void    bpf_mcopy __P((const void *, void *, size_t));
 static int     bpf_movein __P((struct uio *, int,
-                   struct mbuf **, struct sockaddr *, int *));
+                   struct mbuf **, struct sockaddr *, struct ifnet *));
 static int     bpf_setif __P((struct bpf_d *, struct ifreq *));
 static void    bpf_timed_out __P((void *));
 static inline void
@@ -164,9 +164,10 @@ static struct filterops bpfread_filtops 
        { 1, NULL, filt_bpfdetach, filt_bpfread };
 
 static int
-bpf_movein(uio, linktype, mp, sockp, datlen)
+bpf_movein(uio, linktype, mp, sockp, ifp)
        register struct uio *uio;
-       int linktype, *datlen;
+       int linktype;
+       struct ifnet *ifp;
        register struct mbuf **mp;
        register struct sockaddr *sockp;
 {
@@ -209,11 +210,18 @@ bpf_movein(uio, linktype, mp, sockp, dat
                break;
 
        case DLT_RAW:
-       case DLT_NULL:
                sockp->sa_family = AF_UNSPEC;
                hlen = 0;
                break;
 
+       case DLT_NULL:
+               sockp->sa_family = AF_UNSPEC;
+               if(strcmp(ifp->if_name, "tun") == 0)
+                       hlen = sizeof(int);
+               else
+                       hlen = 0;
+               break;
+
 #ifdef __FreeBSD__
        case DLT_ATM_RFC1483:
                /*
@@ -235,7 +243,10 @@ bpf_movein(uio, linktype, mp, sockp, dat
        }
 
        len = uio->uio_resid;
-       *datlen = len - hlen;
+
+       if (len - hlen > ifp->if_mtu)
+               return (EMSGSIZE);
+
        if ((unsigned)len > MCLBYTES)
                return (EIO);
 
@@ -619,7 +630,6 @@ bpfwrite(dev, uio, ioflag)
        struct mbuf *m;
        int error, s;
        static struct sockaddr dst;
-       int datlen;
 
        if (d->bd_bif == 0)
                return (ENXIO);
@@ -629,12 +639,9 @@ bpfwrite(dev, uio, ioflag)
        if (uio->uio_resid == 0)
                return (0);
 
-       error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, &datlen);
+       error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst, ifp);
        if (error)
                return (error);
-
-       if (datlen > ifp->if_mtu)
-               return (EMSGSIZE);
 
        if (d->bd_hdrcmplt)
                dst.sa_family = pseudo_AF_HDRCMPLT;
Index: if_tun.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_tun.c,v
retrieving revision 1.74.2.8
diff -u -p -r1.74.2.8 if_tun.c
--- if_tun.c    13 Feb 2002 00:43:11 -0000      1.74.2.8
+++ if_tun.c    6 Jun 2005 07:54:13 -0000
@@ -328,10 +328,8 @@ tunoutput(ifp, m0, dst, rt)
 
        /* BPF write needs to be handled specially */
        if (dst->sa_family == AF_UNSPEC) {
-               dst->sa_family = *(mtod(m0, int *));
-               m0->m_len -= sizeof(int);
-               m0->m_pkthdr.len -= sizeof(int);
-               m0->m_data += sizeof(int);
+               bcopy(dst->sa_data, &s, 4);
+               dst->sa_family = s; 
        }
 
        if (ifp->if_bpf) {
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to