From owner-svn-src-all@FreeBSD.ORG Thu Apr 28 16:18:31 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 118241065672; Thu, 28 Apr 2011 16:18:31 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id F09BB8FC08; Thu, 28 Apr 2011 16:18:30 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p3SGIUcV030641; Thu, 28 Apr 2011 16:18:30 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p3SGIUqr030633; Thu, 28 Apr 2011 16:18:30 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201104281618.p3SGIUqr030633@svn.freebsd.org> From: Hans Petter Selasky Date: Thu, 28 Apr 2011 16:18:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r221174 - in stable/8: sbin/geom/class/sched sbin/ifconfig sys/conf sys/dev/usb sys/dev/usb/controller sys/modules/usb/usb sys/net usr.sbin usr.sbin/bsnmpd/modules/snmp_hostres usr.sbin... X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Apr 2011 16:18:31 -0000 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 #include +#include /* 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 #include #include +#include +#include +#include #include #include @@ -55,1623 +58,58 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * 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 ***