diff --git a/vendor/github.com/google/gopacket/pcap/pcap.go b/vendor/github.com/google/gopacket/pcap/pcap.go
new file mode 100644
index 0000000..6a4ef63
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/pcap.go
@@ -0,0 +1,866 @@
+// Copyright 2012 Google, Inc. All rights reserved.
+// Copyright 2009-2011 Andreas Krennmair. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package pcap
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"reflect"
+	"runtime"
+	"strconv"
+	"sync"
+	"sync/atomic"
+	"syscall"
+	"time"
+	"unsafe"
+
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+)
+
+// ErrNotActive is returned if handle is not activated
+const ErrNotActive = pcapErrorNotActivated
+
+// MaxBpfInstructions is the maximum number of BPF instructions supported (BPF_MAXINSNS),
+// taken from Linux kernel: include/uapi/linux/bpf_common.h
+//
+// https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf_common.h
+const MaxBpfInstructions = 4096
+
+// 8 bytes per instruction, max 4096 instructions
+const bpfInstructionBufferSize = 8 * MaxBpfInstructions
+
+// Handle provides a connection to a pcap handle, allowing users to read packets
+// off the wire (Next), inject packets onto the wire (Inject), and
+// perform a number of other functions to affect and understand packet output.
+//
+// Handles are already pcap_activate'd
+type Handle struct {
+	// stop is set to a non-zero value by Handle.Close to signal to
+	// getNextBufPtrLocked to stop trying to read packets
+	// This must be the first entry to ensure alignment for sync.atomic
+	stop uint64
+	// cptr is the handle for the actual pcap C object.
+	cptr           pcapTPtr
+	timeout        time.Duration
+	device         string
+	deviceIndex    int
+	mu             sync.Mutex
+	closeMu        sync.Mutex
+	nanoSecsFactor int64
+
+	// Since pointers to these objects are passed into a C function, if
+	// they're declared locally then the Go compiler thinks they may have
+	// escaped into C-land, so it allocates them on the heap.  This causes a
+	// huge memory hit, so to handle that we store them here instead.
+	pkthdr *pcapPkthdr
+	bufptr *uint8
+}
+
+// Stats contains statistics on how many packets were handled by a pcap handle,
+// and what was done with those packets.
+type Stats struct {
+	PacketsReceived  int
+	PacketsDropped   int
+	PacketsIfDropped int
+}
+
+// Interface describes a single network interface on a machine.
+type Interface struct {
+	Name        string
+	Description string
+	Flags       uint32
+	Addresses   []InterfaceAddress
+}
+
+// Datalink describes the datalink
+type Datalink struct {
+	Name        string
+	Description string
+}
+
+// InterfaceAddress describes an address associated with an Interface.
+// Currently, it's IPv4/6 specific.
+type InterfaceAddress struct {
+	IP        net.IP
+	Netmask   net.IPMask // Netmask may be nil if we were unable to retrieve it.
+	Broadaddr net.IP     // Broadcast address for this IP may be nil
+	P2P       net.IP     // P2P destination address for this IP may be nil
+}
+
+// BPF is a compiled filter program, useful for offline packet matching.
+type BPF struct {
+	orig string
+	bpf  pcapBpfProgram // takes a finalizer, not overriden by outsiders
+	hdr  pcapPkthdr     // allocate on the heap to enable optimizations
+}
+
+// BPFInstruction is a byte encoded structure holding a BPF instruction
+type BPFInstruction struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+
+// BlockForever causes it to block forever waiting for packets, when passed
+// into SetTimeout or OpenLive, while still returning incoming packets to userland relatively
+// quickly.
+const BlockForever = -time.Millisecond * 10
+
+func timeoutMillis(timeout time.Duration) int {
+	// Flip sign if necessary.  See package docs on timeout for reasoning behind this.
+	if timeout < 0 {
+		timeout *= -1
+	}
+	// Round up
+	if timeout != 0 && timeout < time.Millisecond {
+		timeout = time.Millisecond
+	}
+	return int(timeout / time.Millisecond)
+}
+
+// OpenLive opens a device and returns a *Handle.
+// It takes as arguments the name of the device ("eth0"), the maximum size to
+// read for each packet (snaplen), whether to put the interface in promiscuous
+// mode, and a timeout. Warning: this function supports only microsecond timestamps.
+// For nanosecond resolution use an InactiveHandle.
+//
+// See the package documentation for important details regarding 'timeout'.
+func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) {
+	var pro int
+	if promisc {
+		pro = 1
+	}
+
+	p, err := pcapOpenLive(device, int(snaplen), pro, timeoutMillis(timeout))
+	if err != nil {
+		return nil, err
+	}
+	p.timeout = timeout
+	p.device = device
+
+	ifc, err := net.InterfaceByName(device)
+	if err != nil {
+		// The device wasn't found in the OS, but could be "any"
+		// Set index to 0
+		p.deviceIndex = 0
+	} else {
+		p.deviceIndex = ifc.Index
+	}
+
+	p.nanoSecsFactor = 1000
+
+	// Only set the PCAP handle into non-blocking mode if we have a timeout
+	// greater than zero. If the user wants to block forever, we'll let libpcap
+	// handle that.
+	if p.timeout > 0 {
+		if err := p.setNonBlocking(); err != nil {
+			p.pcapClose()
+			return nil, err
+		}
+	}
+
+	return p, nil
+}
+
+// OpenOffline opens a file and returns its contents as a *Handle. Depending on libpcap support and
+// on the timestamp resolution used in the file, nanosecond or microsecond resolution is used
+// internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used
+// to query the actual resolution used.
+func OpenOffline(file string) (handle *Handle, err error) {
+	handle, err = openOffline(file)
+	if err != nil {
+		return
+	}
+	if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano {
+		handle.nanoSecsFactor = 1
+	} else {
+		handle.nanoSecsFactor = 1000
+	}
+	return
+}
+
+// OpenOfflineFile returns contents of input file as a *Handle. Depending on libpcap support and
+// on the timestamp resolution used in the file, nanosecond or microsecond resolution is used
+// internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used
+// to query the actual resolution used.
+func OpenOfflineFile(file *os.File) (handle *Handle, err error) {
+	handle, err = openOfflineFile(file)
+	if err != nil {
+		return
+	}
+	if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano {
+		handle.nanoSecsFactor = 1
+	} else {
+		handle.nanoSecsFactor = 1000
+	}
+	return
+}
+
+// NextError is the return code from a call to Next.
+type NextError int32
+
+// NextError implements the error interface.
+func (n NextError) Error() string {
+	switch n {
+	case NextErrorOk:
+		return "OK"
+	case NextErrorTimeoutExpired:
+		return "Timeout Expired"
+	case NextErrorReadError:
+		return "Read Error"
+	case NextErrorNoMorePackets:
+		return "No More Packets In File"
+	case NextErrorNotActivated:
+		return "Not Activated"
+	}
+	return strconv.Itoa(int(n))
+}
+
+// NextError values.
+const (
+	NextErrorOk             NextError = 1
+	NextErrorTimeoutExpired NextError = 0
+	NextErrorReadError      NextError = -1
+	// NextErrorNoMorePackets is returned when reading from a file (OpenOffline) and
+	// EOF is reached.  When this happens, Next() returns io.EOF instead of this.
+	NextErrorNoMorePackets NextError = -2
+	NextErrorNotActivated  NextError = -3
+)
+
+// ReadPacketData returns the next packet read from the pcap handle, along with an error
+// code associated with that packet.  If the packet is read successfully, the
+// returned error is nil.
+func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
+	p.mu.Lock()
+	err = p.getNextBufPtrLocked(&ci)
+	if err == nil {
+		data = make([]byte, ci.CaptureLength)
+		copy(data, (*(*[1 << 30]byte)(unsafe.Pointer(p.bufptr)))[:])
+	}
+	p.mu.Unlock()
+	if err == NextErrorTimeoutExpired {
+		runtime.Gosched()
+	}
+	return
+}
+
+type activateError int
+
+const (
+	aeNoError      = activateError(0)
+	aeActivated    = activateError(pcapErrorActivated)
+	aePromisc      = activateError(pcapWarningPromisc)
+	aeNoSuchDevice = activateError(pcapErrorNoSuchDevice)
+	aeDenied       = activateError(pcapErrorDenied)
+	aeNotUp        = activateError(pcapErrorNotUp)
+	aeWarning      = activateError(pcapWarning)
+)
+
+func (a activateError) Error() string {
+	switch a {
+	case aeNoError:
+		return "No Error"
+	case aeActivated:
+		return "Already Activated"
+	case aePromisc:
+		return "Cannot set as promisc"
+	case aeNoSuchDevice:
+		return "No Such Device"
+	case aeDenied:
+		return "Permission Denied"
+	case aeNotUp:
+		return "Interface Not Up"
+	case aeWarning:
+		return fmt.Sprintf("Warning: %v", activateErrMsg.Error())
+	default:
+		return fmt.Sprintf("unknown activated error: %d", a)
+	}
+}
+
+// getNextBufPtrLocked is shared code for ReadPacketData and
+// ZeroCopyReadPacketData.
+func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error {
+	if !p.isOpen() {
+		return io.EOF
+	}
+
+	// set after we have call waitForPacket for the first time
+	var waited bool
+
+	for atomic.LoadUint64(&p.stop) == 0 {
+		// try to read a packet if one is immediately available
+		result := p.pcapNextPacketEx()
+
+		switch result {
+		case NextErrorOk:
+			sec := p.pkthdr.getSec()
+			// convert micros to nanos
+			nanos := int64(p.pkthdr.getUsec()) * p.nanoSecsFactor
+
+			ci.Timestamp = time.Unix(sec, nanos)
+			ci.CaptureLength = p.pkthdr.getCaplen()
+			ci.Length = p.pkthdr.getLen()
+			ci.InterfaceIndex = p.deviceIndex
+
+			return nil
+		case NextErrorNoMorePackets:
+			// no more packets, return EOF rather than libpcap-specific error
+			return io.EOF
+		case NextErrorTimeoutExpired:
+			// we've already waited for a packet and we're supposed to time out
+			//
+			// we should never actually hit this if we were passed BlockForever
+			// since we should block on C.pcap_next_ex until there's a packet
+			// to read.
+			if waited && p.timeout > 0 {
+				return result
+			}
+
+			// wait for packet before trying again
+			p.waitForPacket()
+			waited = true
+		default:
+			return result
+		}
+	}
+
+	// stop must be set
+	return io.EOF
+}
+
+// ZeroCopyReadPacketData reads the next packet off the wire, and returns its data.
+// The slice returned by ZeroCopyReadPacketData points to bytes owned by the
+// the Handle.  Each call to ZeroCopyReadPacketData invalidates any data previously
+// returned by ZeroCopyReadPacketData.  Care must be taken not to keep pointers
+// to old bytes when using ZeroCopyReadPacketData... if you need to keep data past
+// the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies
+// the bytes into a new buffer for you.
+//  data1, _, _ := handle.ZeroCopyReadPacketData()
+//  // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around.
+//  data2, _, _ := handle.ZeroCopyReadPacketData()  // invalidates bytes in data1
+func (p *Handle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
+	p.mu.Lock()
+	err = p.getNextBufPtrLocked(&ci)
+	if err == nil {
+		slice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
+		slice.Data = uintptr(unsafe.Pointer(p.bufptr))
+		slice.Len = ci.CaptureLength
+		slice.Cap = ci.CaptureLength
+	}
+	p.mu.Unlock()
+	if err == NextErrorTimeoutExpired {
+		runtime.Gosched()
+	}
+	return
+}
+
+// Close closes the underlying pcap handle.
+func (p *Handle) Close() {
+	p.closeMu.Lock()
+	defer p.closeMu.Unlock()
+
+	if !p.isOpen() {
+		return
+	}
+
+	atomic.StoreUint64(&p.stop, 1)
+
+	// wait for packet reader to stop
+	p.mu.Lock()
+	defer p.mu.Unlock()
+
+	p.pcapClose()
+}
+
+// Error returns the current error associated with a pcap handle (pcap_geterr).
+func (p *Handle) Error() error {
+	return p.pcapGeterr()
+}
+
+// Stats returns statistics on the underlying pcap handle.
+func (p *Handle) Stats() (stat *Stats, err error) {
+	return p.pcapStats()
+}
+
+// ListDataLinks obtains a list of all possible data link types supported for an interface.
+func (p *Handle) ListDataLinks() (datalinks []Datalink, err error) {
+	return p.pcapListDatalinks()
+}
+
+// compileBPFFilter always returns an allocated C.struct_bpf_program
+// It is the callers responsibility to free the memory again, e.g.
+//
+//    C.pcap_freecode(&bpf)
+//
+func (p *Handle) compileBPFFilter(expr string) (pcapBpfProgram, error) {
+	var maskp = uint32(pcapNetmaskUnknown)
+
+	// Only do the lookup on network interfaces.
+	// No device indicates we're handling a pcap file.
+	if len(p.device) > 0 {
+		var err error
+		_, maskp, err = pcapLookupnet(p.device)
+		if err != nil {
+			// We can't lookup the network, but that could be because the interface
+			// doesn't have an IPv4.
+			maskp = uint32(pcapNetmaskUnknown)
+		}
+	}
+
+	return p.pcapCompile(expr, maskp)
+}
+
+// CompileBPFFilter compiles and returns a BPF filter with given a link type and capture length.
+func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) ([]BPFInstruction, error) {
+	h, err := pcapOpenDead(linkType, captureLength)
+	if err != nil {
+		return nil, err
+	}
+	defer h.Close()
+	return h.CompileBPFFilter(expr)
+}
+
+// CompileBPFFilter compiles and returns a BPF filter for the pcap handle.
+func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error) {
+	bpf, err := p.compileBPFFilter(expr)
+	defer bpf.free()
+	if err != nil {
+		return nil, err
+	}
+
+	return bpf.toBPFInstruction(), nil
+}
+
+// SetBPFFilter compiles and sets a BPF filter for the pcap handle.
+func (p *Handle) SetBPFFilter(expr string) (err error) {
+	bpf, err := p.compileBPFFilter(expr)
+	defer bpf.free()
+	if err != nil {
+		return err
+	}
+
+	return p.pcapSetfilter(bpf)
+}
+
+// SetBPFInstructionFilter may be used to apply a filter in BPF asm byte code format.
+//
+// Simplest way to generate BPF asm byte code is with tcpdump:
+//     tcpdump -dd 'udp'
+//
+// The output may be used directly to add a filter, e.g.:
+//     bpfInstructions := []pcap.BpfInstruction{
+//			{0x28, 0, 0, 0x0000000c},
+//			{0x15, 0, 9, 0x00000800},
+//			{0x30, 0, 0, 0x00000017},
+//			{0x15, 0, 7, 0x00000006},
+//			{0x28, 0, 0, 0x00000014},
+//			{0x45, 5, 0, 0x00001fff},
+//			{0xb1, 0, 0, 0x0000000e},
+//			{0x50, 0, 0, 0x0000001b},
+//			{0x54, 0, 0, 0x00000012},
+//			{0x15, 0, 1, 0x00000012},
+//			{0x6, 0, 0, 0x0000ffff},
+//			{0x6, 0, 0, 0x00000000},
+//		}
+//
+// An other posibility is to write the bpf code in bpf asm.
+// Documentation: https://www.kernel.org/doc/Documentation/networking/filter.txt
+//
+// To compile the code use bpf_asm from
+// https://github.com/torvalds/linux/tree/master/tools/net
+//
+// The following command may be used to convert bpf_asm output to c/go struct, usable for SetBPFFilterByte:
+// bpf_asm -c tcp.bpf
+func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err error) {
+	bpf, err := bpfInstructionFilter(bpfInstructions)
+	if err != nil {
+		return err
+	}
+	defer bpf.free()
+
+	return p.pcapSetfilter(bpf)
+}
+
+func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf pcapBpfProgram, err error) {
+	if len(bpfInstructions) < 1 {
+		return bpf, errors.New("bpfInstructions must not be empty")
+	}
+
+	if len(bpfInstructions) > MaxBpfInstructions {
+		return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions)
+	}
+
+	return pcapBpfProgramFromInstructions(bpfInstructions), nil
+}
+
+// NewBPF compiles the given string into a new filter program.
+//
+// BPF filters need to be created from activated handles, because they need to
+// know the underlying link type to correctly compile their offsets.
+func (p *Handle) NewBPF(expr string) (*BPF, error) {
+	bpf := &BPF{orig: expr}
+
+	var err error
+	bpf.bpf, err = p.pcapCompile(expr, pcapNetmaskUnknown)
+	if err != nil {
+		return nil, err
+	}
+
+	runtime.SetFinalizer(bpf, destroyBPF)
+	return bpf, nil
+}
+
+// NewBPF allows to create a BPF without requiring an existing handle.
+// This allows to match packets obtained from a-non GoPacket capture source
+// to be matched.
+//
+// 	buf := make([]byte, MaxFrameSize)
+// 	bpfi, _ := pcap.NewBPF(layers.LinkTypeEthernet, MaxFrameSize, "icmp")
+// 	n, _ := someIO.Read(buf)
+// 	ci := gopacket.CaptureInfo{CaptureLength: n, Length: n}
+// 	if bpfi.Matches(ci, buf) {
+// 		doSomething()
+// 	}
+func NewBPF(linkType layers.LinkType, captureLength int, expr string) (*BPF, error) {
+	h, err := pcapOpenDead(linkType, captureLength)
+	if err != nil {
+		return nil, err
+	}
+	defer h.Close()
+	return h.NewBPF(expr)
+}
+
+// NewBPFInstructionFilter sets the given BPFInstructions as new filter program.
+//
+// More details see func SetBPFInstructionFilter
+//
+// BPF filters need to be created from activated handles, because they need to
+// know the underlying link type to correctly compile their offsets.
+func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error) {
+	var err error
+	bpf := &BPF{orig: "BPF Instruction Filter"}
+
+	bpf.bpf, err = bpfInstructionFilter(bpfInstructions)
+	if err != nil {
+		return nil, err
+	}
+
+	runtime.SetFinalizer(bpf, destroyBPF)
+	return bpf, nil
+}
+func destroyBPF(bpf *BPF) {
+	bpf.bpf.free()
+}
+
+// String returns the original string this BPF filter was compiled from.
+func (b *BPF) String() string {
+	return b.orig
+}
+
+// Matches returns true if the given packet data matches this filter.
+func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool {
+	return b.pcapOfflineFilter(ci, data)
+}
+
+// Version returns pcap_lib_version.
+func Version() string {
+	return pcapLibVersion()
+}
+
+// LinkType returns pcap_datalink, as a layers.LinkType.
+func (p *Handle) LinkType() layers.LinkType {
+	return p.pcapDatalink()
+}
+
+// SetLinkType calls pcap_set_datalink on the pcap handle.
+func (p *Handle) SetLinkType(dlt layers.LinkType) error {
+	return p.pcapSetDatalink(dlt)
+}
+
+// DatalinkValToName returns pcap_datalink_val_to_name as string
+func DatalinkValToName(dlt int) string {
+	return pcapDatalinkValToName(dlt)
+}
+
+// DatalinkValToDescription returns pcap_datalink_val_to_description as string
+func DatalinkValToDescription(dlt int) string {
+	return pcapDatalinkValToDescription(dlt)
+}
+
+// DatalinkNameToVal returns pcap_datalink_name_to_val as int
+func DatalinkNameToVal(name string) int {
+	return pcapDatalinkNameToVal(name)
+}
+
+// FindAllDevs attempts to enumerate all interfaces on the current machine.
+func FindAllDevs() (ifs []Interface, err error) {
+	alldevsp, err := pcapFindAllDevs()
+	if err != nil {
+		return nil, err
+	}
+	defer alldevsp.free()
+
+	for alldevsp.next() {
+		var iface Interface
+		iface.Name = alldevsp.name()
+		iface.Description = alldevsp.description()
+		iface.Addresses = findalladdresses(alldevsp.addresses())
+		iface.Flags = alldevsp.flags()
+		ifs = append(ifs, iface)
+	}
+	return
+}
+
+func findalladdresses(addresses pcapAddresses) (retval []InterfaceAddress) {
+	// TODO - make it support more than IPv4 and IPv6?
+	retval = make([]InterfaceAddress, 0, 1)
+	for addresses.next() {
+		// Strangely, it appears that in some cases, we get a pcap address back from
+		// pcap_findalldevs with a nil .addr.  It appears that we can skip over
+		// these.
+		if addresses.addr() == nil {
+			continue
+		}
+		var a InterfaceAddress
+		var err error
+		if a.IP, err = sockaddrToIP(addresses.addr()); err != nil {
+			continue
+		}
+		// To be safe, we'll also check for netmask.
+		if addresses.netmask() == nil {
+			continue
+		}
+		if a.Netmask, err = sockaddrToIP(addresses.netmask()); err != nil {
+			// If we got an IP address but we can't get a netmask, just return the IP
+			// address.
+			a.Netmask = nil
+		}
+		if a.Broadaddr, err = sockaddrToIP(addresses.broadaddr()); err != nil {
+			a.Broadaddr = nil
+		}
+		if a.P2P, err = sockaddrToIP(addresses.dstaddr()); err != nil {
+			a.P2P = nil
+		}
+		retval = append(retval, a)
+	}
+	return
+}
+
+func sockaddrToIP(rsa *syscall.RawSockaddr) (IP []byte, err error) {
+	if rsa == nil {
+		err = errors.New("Value not set")
+		return
+	}
+	switch rsa.Family {
+	case syscall.AF_INET:
+		pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
+		IP = make([]byte, 4)
+		for i := 0; i < len(IP); i++ {
+			IP[i] = pp.Addr[i]
+		}
+		return
+	case syscall.AF_INET6:
+		pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
+		IP = make([]byte, 16)
+		for i := 0; i < len(IP); i++ {
+			IP[i] = pp.Addr[i]
+		}
+		return
+	}
+	err = errors.New("Unsupported address type")
+	return
+}
+
+// WritePacketData calls pcap_sendpacket, injecting the given data into the pcap handle.
+func (p *Handle) WritePacketData(data []byte) (err error) {
+	return p.pcapSendpacket(data)
+}
+
+// Direction is used by Handle.SetDirection.
+type Direction uint8
+
+// Direction values for Handle.SetDirection.
+const (
+	DirectionIn    = Direction(pcapDIN)
+	DirectionOut   = Direction(pcapDOUT)
+	DirectionInOut = Direction(pcapDINOUT)
+)
+
+// SetDirection sets the direction for which packets will be captured.
+func (p *Handle) SetDirection(direction Direction) error {
+	if direction != DirectionIn && direction != DirectionOut && direction != DirectionInOut {
+		return fmt.Errorf("Invalid direction: %v", direction)
+	}
+	return p.pcapSetdirection(direction)
+}
+
+// SnapLen returns the snapshot length
+func (p *Handle) SnapLen() int {
+	return p.pcapSnapshot()
+}
+
+// Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution.
+func (p *Handle) Resolution() gopacket.TimestampResolution {
+	if p.nanoSecsFactor == 1 {
+		return gopacket.TimestampResolutionMicrosecond
+	}
+	return gopacket.TimestampResolutionNanosecond
+}
+
+// TimestampSource tells PCAP which type of timestamp to use for packets.
+type TimestampSource int
+
+// String returns the timestamp type as a human-readable string.
+func (t TimestampSource) String() string {
+	return t.pcapTstampTypeValToName()
+}
+
+// TimestampSourceFromString translates a string into a timestamp type, case
+// insensitive.
+func TimestampSourceFromString(s string) (TimestampSource, error) {
+	return pcapTstampTypeNameToVal(s)
+}
+
+// InactiveHandle allows you to call pre-pcap_activate functions on your pcap
+// handle to set it up just the way you'd like.
+type InactiveHandle struct {
+	// cptr is the handle for the actual pcap C object.
+	cptr        pcapTPtr
+	device      string
+	deviceIndex int
+	timeout     time.Duration
+}
+
+// holds the err messoge in case activation returned a Warning
+var activateErrMsg error
+
+// Error returns the current error associated with a pcap handle (pcap_geterr).
+func (p *InactiveHandle) Error() error {
+	return p.pcapGeterr()
+}
+
+// Activate activates the handle.  The current InactiveHandle becomes invalid
+// and all future function calls on it will fail.
+func (p *InactiveHandle) Activate() (*Handle, error) {
+	// ignore error with set_tstamp_precision, since the actual precision is queried later anyway
+	pcapSetTstampPrecision(p.cptr, pcapTstampPrecisionNano)
+	handle, err := p.pcapActivate()
+	if err != aeNoError {
+		if err == aeWarning {
+			activateErrMsg = p.Error()
+		}
+		return nil, err
+	}
+	handle.timeout = p.timeout
+	if p.timeout > 0 {
+		if err := handle.setNonBlocking(); err != nil {
+			handle.pcapClose()
+			return nil, err
+		}
+	}
+	handle.device = p.device
+	handle.deviceIndex = p.deviceIndex
+	if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano {
+		handle.nanoSecsFactor = 1
+	} else {
+		handle.nanoSecsFactor = 1000
+	}
+	return handle, nil
+}
+
+// CleanUp cleans up any stuff left over from a successful or failed building
+// of a handle.
+func (p *InactiveHandle) CleanUp() {
+	p.pcapClose()
+}
+
+// NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle.
+// Callers of NewInactiveHandle should immediately defer 'CleanUp', as in:
+//   inactive := NewInactiveHandle("eth0")
+//   defer inactive.CleanUp()
+func NewInactiveHandle(device string) (*InactiveHandle, error) {
+	// Try to get the interface index, but iy could be something like "any"
+	// in which case use 0, which doesn't exist in nature
+	deviceIndex := 0
+	ifc, err := net.InterfaceByName(device)
+	if err == nil {
+		deviceIndex = ifc.Index
+	}
+
+	// This copies a bunch of the pcap_open_live implementation from pcap.c:
+	handle, err := pcapCreate(device)
+	if err != nil {
+		return nil, err
+	}
+	handle.device = device
+	handle.deviceIndex = deviceIndex
+	return handle, nil
+}
+
+// SetSnapLen sets the snap length (max bytes per packet to capture).
+func (p *InactiveHandle) SetSnapLen(snaplen int) error {
+	return p.pcapSetSnaplen(snaplen)
+}
+
+// SetPromisc sets the handle to either be promiscuous (capture packets
+// unrelated to this host) or not.
+func (p *InactiveHandle) SetPromisc(promisc bool) error {
+	return p.pcapSetPromisc(promisc)
+}
+
+// SetTimeout sets the read timeout for the handle.
+//
+// See the package documentation for important details regarding 'timeout'.
+func (p *InactiveHandle) SetTimeout(timeout time.Duration) error {
+	err := p.pcapSetTimeout(timeout)
+	if err != nil {
+		return err
+	}
+	p.timeout = timeout
+	return nil
+}
+
+// SupportedTimestamps returns a list of supported timstamp types for this
+// handle.
+func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource) {
+	return p.pcapListTstampTypes()
+}
+
+// SetTimestampSource sets the type of timestamp generator PCAP uses when
+// attaching timestamps to packets.
+func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error {
+	return p.pcapSetTstampType(t)
+}
+
+// CannotSetRFMon is returned by SetRFMon if the handle does not allow
+// setting RFMon because pcap_can_set_rfmon returns 0.
+var CannotSetRFMon = errors.New("Cannot set rfmon for this handle")
+
+// SetRFMon turns on radio monitoring mode, similar to promiscuous mode but for
+// wireless networks.  If this mode is enabled, the interface will not need to
+// associate with an access point before it can receive traffic.
+func (p *InactiveHandle) SetRFMon(monitor bool) error {
+	return p.pcapSetRfmon(monitor)
+}
+
+// SetBufferSize sets the buffer size (in bytes) of the handle.
+func (p *InactiveHandle) SetBufferSize(bufferSize int) error {
+	return p.pcapSetBufferSize(bufferSize)
+}
+
+// SetImmediateMode sets (or unsets) the immediate mode of the
+// handle. In immediate mode, packets are delivered to the application
+// as soon as they arrive.  In other words, this overrides SetTimeout.
+func (p *InactiveHandle) SetImmediateMode(mode bool) error {
+	return p.pcapSetImmediateMode(mode)
+}
