Author: hselasky
Date: Thu Apr 28 16:18:30 2011
New Revision: 221174
URL: http://svn.freebsd.org/changeset/base/221174

Log:
  MFC 
r215649,r215764,r215802,r215804,r215810,r215812,r216091,r216267,r218165,r220301,r215651,r215803,r216138,r218010,r217558,r220312,r220314,r215846
 and r216268.
  Backport USB PF and usbdump from head to 8-stable.
  
  Approved by:  thompsa

Added:
  stable/8/sys/dev/usb/usb_pf.c
     - copied, changed from r215649, head/sys/dev/usb/usb_pf.c
  stable/8/sys/dev/usb/usb_pf.h
     - copied, changed from r215649, head/sys/dev/usb/usb_pf.h
     - copied from r215651, head/usr.sbin/usbdump/
Directory Properties:
  stable/8/usr.sbin/usbdump/   (props changed)
Modified:
  stable/8/sbin/ifconfig/ifconfig.c
  stable/8/sys/conf/files
  stable/8/sys/dev/usb/controller/usb_controller.c
  stable/8/sys/dev/usb/usb_bus.h
  stable/8/sys/dev/usb/usb_freebsd.h
  stable/8/sys/dev/usb/usb_transfer.c
  stable/8/sys/dev/usb/usbdi.h
  stable/8/sys/modules/usb/usb/Makefile
  stable/8/sys/net/if.h
  stable/8/usr.sbin/Makefile   (contents, props changed)
  stable/8/usr.sbin/usbdump/usbdump.c
Directory Properties:
  stable/8/sbin/   (props changed)
  stable/8/sbin/atacontrol/   (props changed)
  stable/8/sbin/bsdlabel/   (props changed)
  stable/8/sbin/camcontrol/   (props changed)
  stable/8/sbin/conscontrol/   (props changed)
  stable/8/sbin/ddb/   (props changed)
  stable/8/sbin/devd/   (props changed)
  stable/8/sbin/devfs/   (props changed)
  stable/8/sbin/dhclient/   (props changed)
  stable/8/sbin/dump/   (props changed)
  stable/8/sbin/dumpfs/   (props changed)
  stable/8/sbin/fdisk/   (props changed)
  stable/8/sbin/fsck/   (props changed)
  stable/8/sbin/fsck_ffs/   (props changed)
  stable/8/sbin/fsck_msdosfs/   (props changed)
  stable/8/sbin/fsirand/   (props changed)
  stable/8/sbin/geom/   (props changed)
  stable/8/sbin/geom/class/multipath/   (props changed)
  stable/8/sbin/geom/class/part/   (props changed)
  stable/8/sbin/geom/class/sched/gsched.8   (props changed)
  stable/8/sbin/geom/class/stripe/   (props changed)
  stable/8/sbin/ggate/   (props changed)
  stable/8/sbin/growfs/   (props changed)
  stable/8/sbin/gvinum/   (props changed)
  stable/8/sbin/hastctl/   (props changed)
  stable/8/sbin/hastd/   (props changed)
  stable/8/sbin/ifconfig/   (props changed)
  stable/8/sbin/ipfw/   (props changed)
  stable/8/sbin/iscontrol/   (props changed)
  stable/8/sbin/kldload/   (props changed)
  stable/8/sbin/kldstat/   (props changed)
  stable/8/sbin/mdconfig/   (props changed)
  stable/8/sbin/mksnap_ffs/   (props changed)
  stable/8/sbin/mount/   (props changed)
  stable/8/sbin/mount_cd9660/   (props changed)
  stable/8/sbin/mount_msdosfs/   (props changed)
  stable/8/sbin/mount_nfs/   (props changed)
  stable/8/sbin/mount_unionfs/   (props changed)
  stable/8/sbin/natd/   (props changed)
  stable/8/sbin/newfs/   (props changed)
  stable/8/sbin/newfs_msdos/   (props changed)
  stable/8/sbin/ping6/   (props changed)
  stable/8/sbin/quotacheck/   (props changed)
  stable/8/sbin/reboot/   (props changed)
  stable/8/sbin/restore/   (props changed)
  stable/8/sbin/route/   (props changed)
  stable/8/sbin/routed/   (props changed)
  stable/8/sbin/setkey/   (props changed)
  stable/8/sbin/spppcontrol/   (props changed)
  stable/8/sbin/sysctl/   (props changed)
  stable/8/sbin/tunefs/   (props changed)
  stable/8/sbin/umount/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/usr.sbin/   (props changed)
  stable/8/usr.sbin/acpi/   (props changed)
  stable/8/usr.sbin/arp/   (props changed)
  stable/8/usr.sbin/asf/   (props changed)
  stable/8/usr.sbin/bluetooth/   (props changed)
  stable/8/usr.sbin/bluetooth/bthidcontrol/   (props changed)
  stable/8/usr.sbin/bluetooth/bthidd/   (props changed)
  stable/8/usr.sbin/bluetooth/l2control/   (props changed)
  stable/8/usr.sbin/bluetooth/l2ping/   (props changed)
  stable/8/usr.sbin/boot0cfg/   (props changed)
  stable/8/usr.sbin/bsnmpd/   (props changed)
  stable/8/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c   
(props changed)
  stable/8/usr.sbin/burncd/   (props changed)
  stable/8/usr.sbin/cdcontrol/   (props changed)
  stable/8/usr.sbin/chown/   (props changed)
  stable/8/usr.sbin/config/   (props changed)
  stable/8/usr.sbin/config/SMM.doc/   (props changed)
  stable/8/usr.sbin/cpucontrol/   (props changed)
  stable/8/usr.sbin/crashinfo/   (props changed)
  stable/8/usr.sbin/cron/   (props changed)
  stable/8/usr.sbin/crunch/examples/   (props changed)
  stable/8/usr.sbin/ctm/   (props changed)
  stable/8/usr.sbin/cxgbtool/   (props changed)
  stable/8/usr.sbin/devinfo/   (props changed)
  stable/8/usr.sbin/diskinfo/   (props changed)
  stable/8/usr.sbin/dumpcis/cardinfo.h   (props changed)
  stable/8/usr.sbin/dumpcis/cis.h   (props changed)
  stable/8/usr.sbin/faithd/   (props changed)
  stable/8/usr.sbin/fdcontrol/   (props changed)
  stable/8/usr.sbin/fdformat/   (props changed)
  stable/8/usr.sbin/fdread/   (props changed)
  stable/8/usr.sbin/fdwrite/   (props changed)
  stable/8/usr.sbin/fifolog/   (props changed)
  stable/8/usr.sbin/flowctl/   (props changed)
  stable/8/usr.sbin/freebsd-update/   (props changed)
  stable/8/usr.sbin/i2c/   (props changed)
  stable/8/usr.sbin/inetd/   (props changed)
  stable/8/usr.sbin/iostat/   (props changed)
  stable/8/usr.sbin/jail/   (props changed)
  stable/8/usr.sbin/jls/   (props changed)
  stable/8/usr.sbin/lpr/   (props changed)
  stable/8/usr.sbin/mailwrapper/   (props changed)
  stable/8/usr.sbin/makefs/ffs/ffs_bswap.c   (props changed)
  stable/8/usr.sbin/makefs/ffs/ffs_subr.c   (props changed)
  stable/8/usr.sbin/makefs/ffs/ufs_bswap.h   (props changed)
  stable/8/usr.sbin/makefs/getid.c   (props changed)
  stable/8/usr.sbin/mergemaster/   (props changed)
  stable/8/usr.sbin/mfiutil/   (props changed)
  stable/8/usr.sbin/mountd/   (props changed)
  stable/8/usr.sbin/moused/   (props changed)
  stable/8/usr.sbin/mptutil/   (props changed)
  stable/8/usr.sbin/mtest/   (props changed)
  stable/8/usr.sbin/mtree/   (props changed)
  stable/8/usr.sbin/named/   (props changed)
  stable/8/usr.sbin/ndp/   (props changed)
  stable/8/usr.sbin/newsyslog/   (props changed)
  stable/8/usr.sbin/nfsd/   (props changed)
  stable/8/usr.sbin/nfsdumpstate/   (props changed)
  stable/8/usr.sbin/ntp/   (props changed)
  stable/8/usr.sbin/pciconf/   (props changed)
  stable/8/usr.sbin/periodic/   (props changed)
  stable/8/usr.sbin/pkg_install/   (props changed)
  stable/8/usr.sbin/pmcannotate/   (props changed)
  stable/8/usr.sbin/pmccontrol/   (props changed)
  stable/8/usr.sbin/pmcstat/   (props changed)
  stable/8/usr.sbin/powerd/   (props changed)
  stable/8/usr.sbin/ppp/   (props changed)
  stable/8/usr.sbin/pppctl/   (props changed)
  stable/8/usr.sbin/pstat/   (props changed)
  stable/8/usr.sbin/pw/   (props changed)
  stable/8/usr.sbin/rpc.lockd/   (props changed)
  stable/8/usr.sbin/rpc.umntall/   (props changed)
  stable/8/usr.sbin/rpcbind/   (props changed)
  stable/8/usr.sbin/rtadvd/   (props changed)
  stable/8/usr.sbin/rtsold/   (props changed)
  stable/8/usr.sbin/sade/   (props changed)
  stable/8/usr.sbin/service/   (props changed)
  stable/8/usr.sbin/services_mkdb/   (props changed)
  stable/8/usr.sbin/setfmac/   (props changed)
  stable/8/usr.sbin/setpmac/   (props changed)
  stable/8/usr.sbin/smbmsg/   (props changed)
  stable/8/usr.sbin/sysinstall/   (props changed)
  stable/8/usr.sbin/syslogd/   (props changed)
  stable/8/usr.sbin/traceroute/   (props changed)
  stable/8/usr.sbin/traceroute6/   (props changed)
  stable/8/usr.sbin/tzsetup/   (props changed)
  stable/8/usr.sbin/uathload/   (props changed)
  stable/8/usr.sbin/ugidfw/   (props changed)
  stable/8/usr.sbin/uhsoctl/   (props changed)
  stable/8/usr.sbin/usbconfig/   (props changed)
  stable/8/usr.sbin/vidcontrol/   (props changed)
  stable/8/usr.sbin/watchdogd/   (props changed)
  stable/8/usr.sbin/wpa/   (props changed)
  stable/8/usr.sbin/ypserv/   (props changed)
  stable/8/usr.sbin/zic/   (props changed)

Modified: stable/8/sbin/ifconfig/ifconfig.c
==============================================================================
--- stable/8/sbin/ifconfig/ifconfig.c   Thu Apr 28 16:02:05 2011        
(r221173)
+++ stable/8/sbin/ifconfig/ifconfig.c   Thu Apr 28 16:18:30 2011        
(r221174)
@@ -305,6 +305,8 @@ main(int argc, char *argv[])
                }
                cp = ifa->ifa_name;
 
+               if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0)
+                       continue;
                if (downonly && (ifa->ifa_flags & IFF_UP) != 0)
                        continue;
                if (uponly && (ifa->ifa_flags & IFF_UP) == 0)

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files     Thu Apr 28 16:02:05 2011        (r221173)
+++ stable/8/sys/conf/files     Thu Apr 28 16:18:30 2011        (r221174)
@@ -1749,6 +1749,7 @@ dev/usb/usb_lookup.c              optional usb
 dev/usb/usb_mbuf.c             optional usb
 dev/usb/usb_msctest.c          optional usb
 dev/usb/usb_parse.c            optional usb
+dev/usb/usb_pf.c               optional usb
 dev/usb/usb_process.c          optional usb
 dev/usb/usb_request.c          optional usb
 dev/usb/usb_transfer.c         optional usb

Modified: stable/8/sys/dev/usb/controller/usb_controller.c
==============================================================================
--- stable/8/sys/dev/usb/controller/usb_controller.c    Thu Apr 28 16:02:05 
2011        (r221173)
+++ stable/8/sys/dev/usb/controller/usb_controller.c    Thu Apr 28 16:18:30 
2011        (r221174)
@@ -60,6 +60,7 @@
 
 #include <dev/usb/usb_controller.h>
 #include <dev/usb/usb_bus.h>
+#include <dev/usb/usb_pf.h>
 
 /* function prototypes  */
 
@@ -205,6 +206,9 @@ usb_detach(device_t dev)
 
        usb_proc_free(&bus->control_xfer_proc);
 
+#if USB_HAVE_PF
+       usbpf_detach(bus);
+#endif
        return (0);
 }
 
@@ -433,6 +437,9 @@ usb_attach_sub(device_t dev, struct usb_
                usb_devclass_ptr = devclass_find("usbus");
        mtx_unlock(&Giant);
 
+#if USB_HAVE_PF
+       usbpf_attach(bus);
+#endif
        /* Initialise USB process messages */
        bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
        bus->explore_msg[0].bus = bus;
@@ -595,3 +602,4 @@ usb_bus_mem_free_all(struct usb_bus *bus
 
        mtx_destroy(&bus->bus_mtx);
 }
+

Modified: stable/8/sys/dev/usb/usb_bus.h
==============================================================================
--- stable/8/sys/dev/usb/usb_bus.h      Thu Apr 28 16:02:05 2011        
(r221173)
+++ stable/8/sys/dev/usb/usb_bus.h      Thu Apr 28 16:18:30 2011        
(r221174)
@@ -86,6 +86,8 @@ struct usb_bus {
        struct usb_bus_methods *methods;        /* filled by HC driver */
        struct usb_device **devices;
 
+       struct ifnet *ifp;      /* only for USB Packet Filter */
+
        usb_power_mask_t hw_power_state;        /* see USB_HW_POWER_XXX */
        usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
 

Modified: stable/8/sys/dev/usb/usb_freebsd.h
==============================================================================
--- stable/8/sys/dev/usb/usb_freebsd.h  Thu Apr 28 16:02:05 2011        
(r221173)
+++ stable/8/sys/dev/usb/usb_freebsd.h  Thu Apr 28 16:18:30 2011        
(r221174)
@@ -40,6 +40,7 @@
 #define        USB_HAVE_TT_SUPPORT 1
 #define        USB_HAVE_POWERD 1
 #define        USB_HAVE_MSCTEST 1
+#define        USB_HAVE_PF 1
 
 #define        USB_TD_GET_PROC(td) (td)->td_proc
 #define        USB_PROC_GET_GID(td) (td)->p_pgid

Copied and modified: stable/8/sys/dev/usb/usb_pf.c (from r215649, 
head/sys/dev/usb/usb_pf.c)
==============================================================================
--- head/sys/dev/usb/usb_pf.c   Mon Nov 22 01:11:28 2010        (r215649, copy 
source)
+++ stable/8/sys/dev/usb/usb_pf.c       Thu Apr 28 16:18:30 2011        
(r221174)
@@ -43,6 +43,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
+#include <sys/sysctl.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -55,1623 +58,58 @@ __FBSDID("$FreeBSD$");
 #include <dev/usb/usb_pf.h>
 #include <dev/usb/usb_transfer.h>
 
-/*
- * All usbpf implementations are extracted from bpf(9) APIs and it's
- * specialized for USB packet filtering between the driver and the host
- * controller.
- */
-
-MALLOC_DEFINE(M_USBPF, "USBPktFilter", "USB Packet Filter");
-
-/*
- * Rotate the packet buffers in descriptor ud.  Move the store buffer into the
- * hold slot, and the free buffer ino the store slot.  Zero the length of the
- * new store buffer.  Descriptor lock should be held.
- */
-#define        USBPF_ROTATE_BUFFERS(ud)        do {                            
\
-       (ud)->ud_hbuf = (ud)->ud_sbuf;                                  \
-       (ud)->ud_hlen = (ud)->ud_slen;                                  \
-       (ud)->ud_sbuf = (ud)->ud_fbuf;                                  \
-       (ud)->ud_slen = 0;                                              \
-       (ud)->ud_fbuf = NULL;                                           \
-       usbpf_bufheld(ud);                                              \
-} while (0)
+static int usb_no_pf;
 
-#ifndef __i386__
-#define        USBPF_ALIGN
-#endif
-
-#ifndef USBPF_ALIGN
-#define        USBPF_EXTRACT_SHORT(p)  ((u_int16_t)ntohs(*(u_int16_t *)p))
-#define        USBPF_EXTRACT_LONG(p)   (ntohl(*(u_int32_t *)p))
-#else
-#define        USBPF_EXTRACT_SHORT(p)                                          
\
-       ((u_int16_t)                                                    \
-           ((u_int16_t)*((u_char *)p+0)<<8|                            \
-               (u_int16_t)*((u_char *)p+1)<<0))
-#define        USBPF_EXTRACT_LONG(p)                                           
\
-       ((u_int32_t)*((u_char *)p+0)<<24|                               \
-           (u_int32_t)*((u_char *)p+1)<<16|                            \
-           (u_int32_t)*((u_char *)p+2)<<8|                             \
-           (u_int32_t)*((u_char *)p+3)<<0)
-#endif
-
-/*
- * Number of scratch memory words (for USBPF_LD|USBPF_MEM and USBPF_ST).
- */
-#define        USBPF_MEMWORDS           16
-
-/* Values for ud_state */
-#define        USBPF_IDLE              0       /* no select in progress */
-#define        USBPF_WAITING           1       /* waiting for read timeout in 
select */
-#define        USBPF_TIMED_OUT         2       /* read timeout has expired in 
select */
-
-#define        PRIUSB                  26      /* interruptible */
-
-/* Frame directions */
-enum usbpf_direction {
-       USBPF_D_IN,     /* See incoming frames */
-       USBPF_D_INOUT,  /* See incoming and outgoing frames */
-       USBPF_D_OUT     /* See outgoing frames */
-};
-
-static void    usbpf_append_bytes(struct usbpf_d *, caddr_t, u_int, void *,
-                   u_int);
-static void    usbpf_attachd(struct usbpf_d *, struct usbpf_if *);
-static void    usbpf_detachd(struct usbpf_d *);
-static int     usbpf_canfreebuf(struct usbpf_d *);
-static void    usbpf_buf_reclaimed(struct usbpf_d *);
-static int     usbpf_canwritebuf(struct usbpf_d *);
-
-static d_open_t        usbpf_open;
-static d_read_t        usbpf_read;
-static d_write_t       usbpf_write;
-static d_ioctl_t       usbpf_ioctl;
-static d_poll_t        usbpf_poll;
-static d_kqfilter_t    usbpf_kqfilter;
-
-static struct cdevsw usbpf_cdevsw = {
-       .d_version =    D_VERSION,
-       .d_open =       usbpf_open,
-       .d_read =       usbpf_read,
-       .d_write =      usbpf_write,
-       .d_ioctl =      usbpf_ioctl,
-       .d_poll =       usbpf_poll,
-       .d_name =       "usbpf",
-       .d_kqfilter =   usbpf_kqfilter,
-};
-
-static LIST_HEAD(, usbpf_if)   usbpf_iflist;
-static struct mtx      usbpf_mtx;              /* global lock */
-static int usbpf_uifd_cnt;
-
-static int usbpf_bufsize = 4096;
-#define        USBPF_MINBUFSIZE 32
-#define        USBPF_MAXBUFSIZE 0x80000
-static int usbpf_maxbufsize = USBPF_MAXBUFSIZE;
-#define        USBPF_MAXINSNS 512
-static int usbpf_maxinsns = USBPF_MAXINSNS;
-
-static void
-usbpf_buffer_init(struct usbpf_d *ud)
-{
-
-       ud->ud_bufsize = usbpf_bufsize;
-}
-
-/*
- * Free USBPF kernel buffers on device close.
- */
-static void
-usbpf_buffer_free(struct usbpf_d *ud)
-{
-
-       if (ud->ud_sbuf != NULL)
-               free(ud->ud_sbuf, M_USBPF);
-       if (ud->ud_hbuf != NULL)
-               free(ud->ud_hbuf, M_USBPF);
-       if (ud->ud_fbuf != NULL)
-               free(ud->ud_fbuf, M_USBPF);
-
-#ifdef INVARIANTS
-       ud->ud_sbuf = ud->ud_hbuf = ud->ud_fbuf = (caddr_t)~0;
-#endif
-}
-
-static void
-usbpf_buffer_alloc(struct usbpf_d *ud)
-{
-
-       KASSERT(ud->ud_fbuf == NULL, ("%s: ud_fbuf != NULL", __func__));
-       KASSERT(ud->ud_sbuf == NULL, ("%s: ud_sbuf != NULL", __func__));
-       KASSERT(ud->ud_hbuf == NULL, ("%s: ud_hbuf != NULL", __func__));
-
-       ud->ud_fbuf = (caddr_t)malloc(ud->ud_bufsize, M_USBPF, M_WAITOK);
-       ud->ud_sbuf = (caddr_t)malloc(ud->ud_bufsize, M_USBPF, M_WAITOK);
-       ud->ud_hbuf = NULL;
-       ud->ud_slen = 0;
-       ud->ud_hlen = 0;
-}
-
-/*
- * Copy buffer storage to user space in read().
- */
-static int
-usbpf_buffer_uiomove(struct usbpf_d *ud, caddr_t buf, u_int len,
-    struct uio *uio)
-{
-
-       return (uiomove(buf, len, uio));
-}
-
-/*
- * Simple data copy to the current kernel buffer.
- */
-static void
-usbpf_buffer_append_bytes(struct usbpf_d *ud, caddr_t buf, u_int offset,
-    void *src, u_int len)
-{
-       u_char *src_bytes;
-
-       src_bytes = (u_char *)src;
-       bcopy(src_bytes, buf + offset, len);
-}
-
-/*
- * Allocate or resize buffers.
- */
-static int
-usbpf_buffer_ioctl_sblen(struct usbpf_d *ud, u_int *i)
-{
-       u_int size;
-
-       USBPFD_LOCK(ud);
-       if (ud->ud_bif != NULL) {
-               USBPFD_UNLOCK(ud);
-               return (EINVAL);
-       }
-       size = *i;
-       if (size > usbpf_maxbufsize)
-               *i = size = usbpf_maxbufsize;
-       else if (size < USBPF_MINBUFSIZE)
-               *i = size = USBPF_MINBUFSIZE;
-       ud->ud_bufsize = size;
-       USBPFD_UNLOCK(ud);
-       return (0);
-}
-
-static const u_short   usbpf_code_map[] = {
-       0x10ff, /* 0x00-0x0f: 1111111100001000 */
-       0x3070, /* 0x10-0x1f: 0000111000001100 */
-       0x3131, /* 0x20-0x2f: 1000110010001100 */
-       0x3031, /* 0x30-0x3f: 1000110000001100 */
-       0x3131, /* 0x40-0x4f: 1000110010001100 */
-       0x1011, /* 0x50-0x5f: 1000100000001000 */
-       0x1013, /* 0x60-0x6f: 1100100000001000 */
-       0x1010, /* 0x70-0x7f: 0000100000001000 */
-       0x0093, /* 0x80-0x8f: 1100100100000000 */
-       0x0000, /* 0x90-0x9f: 0000000000000000 */
-       0x0000, /* 0xa0-0xaf: 0000000000000000 */
-       0x0002, /* 0xb0-0xbf: 0100000000000000 */
-       0x0000, /* 0xc0-0xcf: 0000000000000000 */
-       0x0000, /* 0xd0-0xdf: 0000000000000000 */
-       0x0000, /* 0xe0-0xef: 0000000000000000 */
-       0x0000  /* 0xf0-0xff: 0000000000000000 */
-};
-
-#define        USBPF_VALIDATE_CODE(c)  \
-    ((c) <= 0xff && (usbpf_code_map[(c) >> 4] & (1 << ((c) & 0xf))) != 0)
-
-/*
- * Return true if the 'fcode' is a valid filter program.
- * The constraints are that each jump be forward and to a valid
- * code.  The code must terminate with either an accept or reject.
- *
- * The kernel needs to be able to verify an application's filter code.
- * Otherwise, a bogus program could easily crash the system.
- */
-static int
-usbpf_validate(const struct usbpf_insn *f, int len)
-{
-       register int i;
-       register const struct usbpf_insn *p;
-
-       /* Do not accept negative length filter. */
-       if (len < 0)
-               return (0);
-
-       /* An empty filter means accept all. */
-       if (len == 0)
-               return (1);
-
-       for (i = 0; i < len; ++i) {
-               p = &f[i];
-               /*
-                * Check that the code is valid.
-                */
-               if (!USBPF_VALIDATE_CODE(p->code))
-                       return (0);
-               /*
-                * Check that that jumps are forward, and within
-                * the code block.
-                */
-               if (USBPF_CLASS(p->code) == USBPF_JMP) {
-                       register u_int offset;
-
-                       if (p->code == (USBPF_JMP|USBPF_JA))
-                               offset = p->k;
-                       else
-                               offset = p->jt > p->jf ? p->jt : p->jf;
-                       if (offset >= (u_int)(len - i) - 1)
-                               return (0);
-                       continue;
-               }
-               /*
-                * Check that memory operations use valid addresses.
-                */
-               if (p->code == USBPF_ST || p->code == USBPF_STX ||
-                   p->code == (USBPF_LD|USBPF_MEM) ||
-                   p->code == (USBPF_LDX|USBPF_MEM)) {
-                       if (p->k >= USBPF_MEMWORDS)
-                               return (0);
-                       continue;
-               }
-               /*
-                * Check for constant division by 0.
-                */
-               if (p->code == (USBPF_ALU|USBPF_DIV|USBPF_K) && p->k == 0)
-                       return (0);
-       }
-       return (USBPF_CLASS(f[len - 1].code) == USBPF_RET);
-}
-
-#ifdef _KERNEL
-#define        MINDEX(m, k) \
-{ \
-       register int len = m->m_len; \
- \
-       while (k >= len) { \
-               k -= len; \
-               m = m->m_next; \
-               if (m == 0) \
-                       return (0); \
-               len = m->m_len; \
-       } \
-}
-
-static u_int16_t       m_xhalf(struct mbuf *m, usbpf_u_int32 k, int *err);
-static u_int32_t       m_xword(struct mbuf *m, usbpf_u_int32 k, int *err);
-
-static u_int32_t
-m_xword(struct mbuf *m, usbpf_u_int32 k, int *err)
-{
-       size_t len;
-       u_char *cp, *np;
-       struct mbuf *m0;
-
-       len = m->m_len;
-       while (k >= len) {
-               k -= len;
-               m = m->m_next;
-               if (m == 0)
-                       goto bad;
-               len = m->m_len;
-       }
-       cp = mtod(m, u_char *) + k;
-       if (len - k >= 4) {
-               *err = 0;
-               return (USBPF_EXTRACT_LONG(cp));
-       }
-       m0 = m->m_next;
-       if (m0 == 0 || m0->m_len + len - k < 4)
-               goto bad;
-       *err = 0;
-       np = mtod(m0, u_char *);
-       switch (len - k) {
-       case 1:
-               return (((u_int32_t)cp[0] << 24) |
-                   ((u_int32_t)np[0] << 16) |
-                   ((u_int32_t)np[1] << 8)  |
-                   (u_int32_t)np[2]);
-
-       case 2:
-               return (((u_int32_t)cp[0] << 24) |
-                   ((u_int32_t)cp[1] << 16) |
-                   ((u_int32_t)np[0] << 8) |
-                   (u_int32_t)np[1]);
-
-       default:
-               return (((u_int32_t)cp[0] << 24) |
-                   ((u_int32_t)cp[1] << 16) |
-                   ((u_int32_t)cp[2] << 8) |
-                   (u_int32_t)np[0]);
-       }
-    bad:
-       *err = 1;
-       return (0);
-}
-
-static u_int16_t
-m_xhalf(struct mbuf *m, usbpf_u_int32 k, int *err)
-{
-       size_t len;
-       u_char *cp;
-       struct mbuf *m0;
-
-       len = m->m_len;
-       while (k >= len) {
-               k -= len;
-               m = m->m_next;
-               if (m == 0)
-                       goto bad;
-               len = m->m_len;
-       }
-       cp = mtod(m, u_char *) + k;
-       if (len - k >= 2) {
-               *err = 0;
-               return (USBPF_EXTRACT_SHORT(cp));
-       }
-       m0 = m->m_next;
-       if (m0 == 0)
-               goto bad;
-       *err = 0;
-       return ((cp[0] << 8) | mtod(m0, u_char *)[0]);
- bad:
-       *err = 1;
-       return (0);
-}
-#endif
-
-/*
- * Execute the filter program starting at pc on the packet p
- * wirelen is the length of the original packet
- * buflen is the amount of data present
- */
-static u_int
-usbpf_filter(const struct usbpf_insn *pc, u_char *p, u_int wirelen,
-    u_int buflen)
-{
-       u_int32_t A = 0, X = 0;
-       usbpf_u_int32 k;
-       u_int32_t mem[USBPF_MEMWORDS];
-
-       /*
-        * XXX temporarily the filter system is disabled because currently it
-        * could not handle the some machine code properly that leads to
-        * kernel crash by invalid usage.
-        */
-       return ((u_int)-1);
-
-       if (pc == NULL)
-               /*
-                * No filter means accept all.
-                */
-               return ((u_int)-1);
-
-       --pc;
-       while (1) {
-               ++pc;
-               switch (pc->code) {
-               default:
-#ifdef _KERNEL
-                       return (0);
-#else
-                       abort();
-#endif
-
-               case USBPF_RET|USBPF_K:
-                       return ((u_int)pc->k);
-
-               case USBPF_RET|USBPF_A:
-                       return ((u_int)A);
-
-               case USBPF_LD|USBPF_W|USBPF_ABS:
-                       k = pc->k;
-                       if (k > buflen || sizeof(int32_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xword((struct mbuf *)p, k, &merr);
-                               if (merr != 0)
-                                       return (0);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-#ifdef USBPF_ALIGN
-                       if (((intptr_t)(p + k) & 3) != 0)
-                               A = USBPF_EXTRACT_LONG(&p[k]);
-                       else
-#endif
-                               A = ntohl(*(int32_t *)(p + k));
-                       continue;
-
-               case USBPF_LD|USBPF_H|USBPF_ABS:
-                       k = pc->k;
-                       if (k > buflen || sizeof(int16_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xhalf((struct mbuf *)p, k, &merr);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = USBPF_EXTRACT_SHORT(&p[k]);
-                       continue;
+SYSCTL_INT(_hw_usb, OID_AUTO, no_pf, CTLFLAG_RW,
+    &usb_no_pf, 0, "Set to disable USB packet filtering");
 
-               case USBPF_LD|USBPF_B|USBPF_ABS:
-                       k = pc->k;
-                       if (k >= buflen) {
-#ifdef _KERNEL
-                               struct mbuf *m;
-
-                               if (buflen != 0)
-                                       return (0);
-                               m = (struct mbuf *)p;
-                               MINDEX(m, k);
-                               A = mtod(m, u_char *)[k];
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = p[k];
-                       continue;
-
-               case USBPF_LD|USBPF_W|USBPF_LEN:
-                       A = wirelen;
-                       continue;
-
-               case USBPF_LDX|USBPF_W|USBPF_LEN:
-                       X = wirelen;
-                       continue;
-
-               case USBPF_LD|USBPF_W|USBPF_IND:
-                       k = X + pc->k;
-                       if (pc->k > buflen || X > buflen - pc->k ||
-                           sizeof(int32_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xword((struct mbuf *)p, k, &merr);
-                               if (merr != 0)
-                                       return (0);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-#ifdef USBPF_ALIGN
-                       if (((intptr_t)(p + k) & 3) != 0)
-                               A = USBPF_EXTRACT_LONG(&p[k]);
-                       else
-#endif
-                               A = ntohl(*(int32_t *)(p + k));
-                       continue;
-
-               case USBPF_LD|USBPF_H|USBPF_IND:
-                       k = X + pc->k;
-                       if (X > buflen || pc->k > buflen - X ||
-                           sizeof(int16_t) > buflen - k) {
-#ifdef _KERNEL
-                               int merr;
-
-                               if (buflen != 0)
-                                       return (0);
-                               A = m_xhalf((struct mbuf *)p, k, &merr);
-                               if (merr != 0)
-                                       return (0);
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = USBPF_EXTRACT_SHORT(&p[k]);
-                       continue;
-
-               case USBPF_LD|USBPF_B|USBPF_IND:
-                       k = X + pc->k;
-                       if (pc->k >= buflen || X >= buflen - pc->k) {
-#ifdef _KERNEL
-                               struct mbuf *m;
-
-                               if (buflen != 0)
-                                       return (0);
-                               m = (struct mbuf *)p;
-                               MINDEX(m, k);
-                               A = mtod(m, u_char *)[k];
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       A = p[k];
-                       continue;
-
-               case USBPF_LDX|USBPF_MSH|USBPF_B:
-                       k = pc->k;
-                       if (k >= buflen) {
-#ifdef _KERNEL
-                               register struct mbuf *m;
-
-                               if (buflen != 0)
-                                       return (0);
-                               m = (struct mbuf *)p;
-                               MINDEX(m, k);
-                               X = (mtod(m, u_char *)[k] & 0xf) << 2;
-                               continue;
-#else
-                               return (0);
-#endif
-                       }
-                       X = (p[pc->k] & 0xf) << 2;
-                       continue;
-
-               case USBPF_LD|USBPF_IMM:
-                       A = pc->k;
-                       continue;
-
-               case USBPF_LDX|USBPF_IMM:
-                       X = pc->k;
-                       continue;
-
-               case USBPF_LD|USBPF_MEM:
-                       A = mem[pc->k];
-                       continue;
-
-               case USBPF_LDX|USBPF_MEM:
-                       X = mem[pc->k];
-                       continue;
-
-               case USBPF_ST:
-                       mem[pc->k] = A;
-                       continue;
-
-               case USBPF_STX:
-                       mem[pc->k] = X;
-                       continue;
-
-               case USBPF_JMP|USBPF_JA:
-                       pc += pc->k;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGT|USBPF_K:
-                       pc += (A > pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGE|USBPF_K:
-                       pc += (A >= pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JEQ|USBPF_K:
-                       pc += (A == pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JSET|USBPF_K:
-                       pc += (A & pc->k) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGT|USBPF_X:
-                       pc += (A > X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JGE|USBPF_X:
-                       pc += (A >= X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JEQ|USBPF_X:
-                       pc += (A == X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_JMP|USBPF_JSET|USBPF_X:
-                       pc += (A & X) ? pc->jt : pc->jf;
-                       continue;
-
-               case USBPF_ALU|USBPF_ADD|USBPF_X:
-                       A += X;
-                       continue;
-
-               case USBPF_ALU|USBPF_SUB|USBPF_X:
-                       A -= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_MUL|USBPF_X:
-                       A *= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_DIV|USBPF_X:
-                       if (X == 0)
-                               return (0);
-                       A /= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_AND|USBPF_X:
-                       A &= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_OR|USBPF_X:
-                       A |= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_LSH|USBPF_X:
-                       A <<= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_RSH|USBPF_X:
-                       A >>= X;
-                       continue;
-
-               case USBPF_ALU|USBPF_ADD|USBPF_K:
-                       A += pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_SUB|USBPF_K:
-                       A -= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_MUL|USBPF_K:
-                       A *= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_DIV|USBPF_K:
-                       A /= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_AND|USBPF_K:
-                       A &= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_OR|USBPF_K:
-                       A |= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_LSH|USBPF_K:
-                       A <<= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_RSH|USBPF_K:
-                       A >>= pc->k;
-                       continue;
-
-               case USBPF_ALU|USBPF_NEG:
-                       A = -A;
-                       continue;
-
-               case USBPF_MISC|USBPF_TAX:
-                       X = A;
-                       continue;
-
-               case USBPF_MISC|USBPF_TXA:
-                       A = X;
-                       continue;
-               }
-       }
-}
-
-static void
-usbpf_free(struct usbpf_d *ud)
-{
-
-       switch (ud->ud_bufmode) {
-       case USBPF_BUFMODE_BUFFER:
-               return (usbpf_buffer_free(ud));
-       default:
-               panic("usbpf_buf_free");
-       }
-}
+TUNABLE_INT("hw.usb.no_pf", &usb_no_pf);
 
-/*
- * Notify the buffer model that a buffer has moved into the hold position.
- */
-static void
-usbpf_bufheld(struct usbpf_d *ud)
-{
-
-       USBPFD_LOCK_ASSERT(ud);
-}
-
-/*
- * Free buffers currently in use by a descriptor.
- * Called on close.
- */
-static void
-usbpf_freed(struct usbpf_d *ud)
-{
-
-       /*
-        * We don't need to lock out interrupts since this descriptor has
-        * been detached from its interface and it yet hasn't been marked
-        * free.
-        */
-       usbpf_free(ud);
-       if (ud->ud_rfilter != NULL)
-               free((caddr_t)ud->ud_rfilter, M_USBPF);
-       if (ud->ud_wfilter != NULL)
-               free((caddr_t)ud->ud_wfilter, M_USBPF);
-       mtx_destroy(&ud->ud_mtx);
-}
-
-/*
- * Close the descriptor by detaching it from its interface,
- * deallocating its buffers, and marking it free.
- */
-static void
-usbpf_dtor(void *data)
-{
-       struct usbpf_d *ud = data;
-
-       USBPFD_LOCK(ud);
-       if (ud->ud_state == USBPF_WAITING)
-               callout_stop(&ud->ud_callout);
-       ud->ud_state = USBPF_IDLE;
-       USBPFD_UNLOCK(ud);
-       funsetown(&ud->ud_sigio);
-       mtx_lock(&usbpf_mtx);
-       if (ud->ud_bif)
-               usbpf_detachd(ud);
-       mtx_unlock(&usbpf_mtx);
-       selwakeuppri(&ud->ud_sel, PRIUSB);
-       knlist_destroy(&ud->ud_sel.si_note);
-       callout_drain(&ud->ud_callout);
-       usbpf_freed(ud);
-       free(ud, M_USBPF);
-}
-
-/*
- * Open device.  Returns ENXIO for illegal minor device number,
- * EBUSY if file is open by another process.
- */
-/* ARGSUSED */
-static int
-usbpf_open(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
-       struct usbpf_d *ud;
-       int error;
-
-       ud = malloc(sizeof(*ud), M_USBPF, M_WAITOK | M_ZERO);
-       error = devfs_set_cdevpriv(ud, usbpf_dtor);
-       if (error != 0) {
-               free(ud, M_USBPF);
-               return (error);
-       }
-
-       usbpf_buffer_init(ud);
-       ud->ud_bufmode = USBPF_BUFMODE_BUFFER;
-       ud->ud_sig = SIGIO;
-       ud->ud_direction = USBPF_D_INOUT;
-       ud->ud_pid = td->td_proc->p_pid;
-       mtx_init(&ud->ud_mtx, devtoname(dev), "usbpf cdev lock", MTX_DEF);
-       callout_init_mtx(&ud->ud_callout, &ud->ud_mtx, 0);
-       knlist_init_mtx(&ud->ud_sel.si_note, &ud->ud_mtx);
-
-       return (0);
-}
-
-static int
-usbpf_uiomove(struct usbpf_d *ud, caddr_t buf, u_int len, struct uio *uio)
-{
-
-       if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER)
-               return (EOPNOTSUPP);
-       return (usbpf_buffer_uiomove(ud, buf, len, uio));
-}
-
-/*
- *  usbpf_read - read next chunk of packets from buffers
- */
-static int
-usbpf_read(struct cdev *dev, struct uio *uio, int ioflag)
-{
-       struct usbpf_d *ud;
-       int error;
-       int non_block;
-       int timed_out;
-
-       error = devfs_get_cdevpriv((void **)&ud);
-       if (error != 0)
-               return (error);
-
-       /*
-        * Restrict application to use a buffer the same size as
-        * as kernel buffers.
-        */
-       if (uio->uio_resid != ud->ud_bufsize)
-               return (EINVAL);
-
-       non_block = ((ioflag & O_NONBLOCK) != 0);
-
-       USBPFD_LOCK(ud);
-       ud->ud_pid = curthread->td_proc->p_pid;
-       if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER) {
-               USBPFD_UNLOCK(ud);
-               return (EOPNOTSUPP);
-       }
-       if (ud->ud_state == USBPF_WAITING)
-               callout_stop(&ud->ud_callout);
-       timed_out = (ud->ud_state == USBPF_TIMED_OUT);
-       ud->ud_state = USBPF_IDLE;
-       /*
-        * If the hold buffer is empty, then do a timed sleep, which
-        * ends when the timeout expires or when enough packets
-        * have arrived to fill the store buffer.
-        */
-       while (ud->ud_hbuf == NULL) {
-               if (ud->ud_slen != 0) {
-                       /*
-                        * A packet(s) either arrived since the previous
-                        * read or arrived while we were asleep.
-                        */
-                       if (ud->ud_immediate || non_block || timed_out) {
-                               /*
-                                * Rotate the buffers and return what's here
-                                * if we are in immediate mode, non-blocking
-                                * flag is set, or this descriptor timed out.
-                                */
-                               USBPF_ROTATE_BUFFERS(ud);
-                               break;
-                       }
-               }
-
-               /*
-                * No data is available, check to see if the usbpf device
-                * is still pointed at a real interface.  If not, return
-                * ENXIO so that the userland process knows to rebind
-                * it before using it again.
-                */
-               if (ud->ud_bif == NULL) {
-                       USBPFD_UNLOCK(ud);
-                       return (ENXIO);
-               }
-
-               if (non_block) {
-                       USBPFD_UNLOCK(ud);
-                       return (EWOULDBLOCK);
-               }
-               error = msleep(ud, &ud->ud_mtx, PRIUSB|PCATCH,
-                   "uff", ud->ud_rtout);
-               if (error == EINTR || error == ERESTART) {
-                       USBPFD_UNLOCK(ud);
-                       return (error);
-               }
-               if (error == EWOULDBLOCK) {
-                       /*
-                        * On a timeout, return what's in the buffer,
-                        * which may be nothing.  If there is something
-                        * in the store buffer, we can rotate the buffers.
-                        */
-                       if (ud->ud_hbuf)
-                               /*
-                                * We filled up the buffer in between
-                                * getting the timeout and arriving
-                                * here, so we don't need to rotate.
-                                */
-                               break;
-
-                       if (ud->ud_slen == 0) {
-                               USBPFD_UNLOCK(ud);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to