Committing vendored dependencies and generated protos

Change-Id: I349c149b513d9de7d9f60bde2c954a939da2fc54
diff --git a/vendor/github.com/google/gopacket/pcap/defs_windows_386.go b/vendor/github.com/google/gopacket/pcap/defs_windows_386.go
new file mode 100644
index 0000000..774e907
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/defs_windows_386.go
@@ -0,0 +1,74 @@
+// Copyright 2019 The GoPacket Authors. 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.
+
+// This file contains necessary structs/constants generated from libpcap headers with cgo -godefs
+// generated with: generate_defs.exe
+// DO NOT MODIFY
+
+package pcap
+
+import "syscall"
+
+const errorBufferSize = 0x100
+
+const (
+	pcapErrorNotActivated    = -0x3
+	pcapErrorActivated       = -0x4
+	pcapWarningPromisc       = 0x2
+	pcapErrorNoSuchDevice    = -0x5
+	pcapErrorDenied          = -0x8
+	pcapErrorNotUp           = -0x9
+	pcapError                = -0x1
+	pcapWarning              = 0x1
+	pcapDIN                  = 0x1
+	pcapDOUT                 = 0x2
+	pcapDINOUT               = 0x0
+	pcapNetmaskUnknown       = 0xffffffff
+	pcapTstampPrecisionMicro = 0x0
+	pcapTstampPrecisionNano  = 0x1
+)
+
+type timeval struct {
+	Sec  int32
+	Usec int32
+}
+type pcapPkthdr struct {
+	Ts     timeval
+	Caplen uint32
+	Len    uint32
+}
+type pcapTPtr uintptr
+type pcapBpfInstruction struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+type pcapBpfProgram struct {
+	Len   uint32
+	Insns *pcapBpfInstruction
+}
+type pcapStats struct {
+	Recv   uint32
+	Drop   uint32
+	Ifdrop uint32
+}
+type pcapCint int32
+type pcapIf struct {
+	Next        *pcapIf
+	Name        *int8
+	Description *int8
+	Addresses   *pcapAddr
+	Flags       uint32
+}
+
+type pcapAddr struct {
+	Next      *pcapAddr
+	Addr      *syscall.RawSockaddr
+	Netmask   *syscall.RawSockaddr
+	Broadaddr *syscall.RawSockaddr
+	Dstaddr   *syscall.RawSockaddr
+}
diff --git a/vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go b/vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go
new file mode 100644
index 0000000..9619215
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go
@@ -0,0 +1,76 @@
+// Copyright 2019 The GoPacket Authors. 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.
+
+// This file contains necessary structs/constants generated from libpcap headers with cgo -godefs
+// generated with: generate_defs.exe
+// DO NOT MODIFY
+
+package pcap
+
+import "syscall"
+
+const errorBufferSize = 0x100
+
+const (
+	pcapErrorNotActivated    = -0x3
+	pcapErrorActivated       = -0x4
+	pcapWarningPromisc       = 0x2
+	pcapErrorNoSuchDevice    = -0x5
+	pcapErrorDenied          = -0x8
+	pcapErrorNotUp           = -0x9
+	pcapError                = -0x1
+	pcapWarning              = 0x1
+	pcapDIN                  = 0x1
+	pcapDOUT                 = 0x2
+	pcapDINOUT               = 0x0
+	pcapNetmaskUnknown       = 0xffffffff
+	pcapTstampPrecisionMicro = 0x0
+	pcapTstampPrecisionNano  = 0x1
+)
+
+type timeval struct {
+	Sec  int32
+	Usec int32
+}
+type pcapPkthdr struct {
+	Ts     timeval
+	Caplen uint32
+	Len    uint32
+}
+type pcapTPtr uintptr
+type pcapBpfInstruction struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+type pcapBpfProgram struct {
+	Len       uint32
+	Pad_cgo_0 [4]byte
+	Insns     *pcapBpfInstruction
+}
+type pcapStats struct {
+	Recv   uint32
+	Drop   uint32
+	Ifdrop uint32
+}
+type pcapCint int32
+type pcapIf struct {
+	Next        *pcapIf
+	Name        *int8
+	Description *int8
+	Addresses   *pcapAddr
+	Flags       uint32
+	Pad_cgo_0   [4]byte
+}
+
+type pcapAddr struct {
+	Next      *pcapAddr
+	Addr      *syscall.RawSockaddr
+	Netmask   *syscall.RawSockaddr
+	Broadaddr *syscall.RawSockaddr
+	Dstaddr   *syscall.RawSockaddr
+}
diff --git a/vendor/github.com/google/gopacket/pcap/doc.go b/vendor/github.com/google/gopacket/pcap/doc.go
new file mode 100644
index 0000000..38b3141
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/doc.go
@@ -0,0 +1,112 @@
+// Copyright 2012 Google, Inc. 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 allows users of gopacket to read packets off the wire or from
+pcap files.
+
+This package is meant to be used with its parent,
+http://github.com/google/gopacket, although it can also be used independently
+if you just want to get packet data from the wire.
+
+Depending on libpcap version, os support, or file timestamp resolution,
+nanosecond resolution is used for the internal timestamps. Returned timestamps
+are always scaled to nanosecond resolution due to the usage of time.Time.
+libpcap must be at least version 1.5 to support nanosecond timestamps. OpenLive
+supports only microsecond resolution.
+
+Reading PCAP Files
+
+The following code can be used to read in data from a pcap file.
+
+ if handle, err := pcap.OpenOffline("/path/to/my/file"); err != nil {
+   panic(err)
+ } else {
+   packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
+   for packet := range packetSource.Packets() {
+     handlePacket(packet)  // Do something with a packet here.
+   }
+ }
+
+Reading Live Packets
+
+The following code can be used to read in data from a live device, in this case
+"eth0". Be aware, that OpenLive only supports microsecond resolution.
+
+ if handle, err := pcap.OpenLive("eth0", 1600, true, pcap.BlockForever); err != nil {
+   panic(err)
+ } else if err := handle.SetBPFFilter("tcp and port 80"); err != nil {  // optional
+   panic(err)
+ } else {
+   packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
+   for packet := range packetSource.Packets() {
+     handlePacket(packet)  // Do something with a packet here.
+   }
+ }
+
+Inactive Handles
+
+Newer PCAP functionality requires the concept of an 'inactive' PCAP handle.
+Instead of constantly adding new arguments to pcap_open_live, users now call
+pcap_create to create a handle, set it up with a bunch of optional function
+calls, then call pcap_activate to activate it.  This library mirrors that
+mechanism, for those that want to expose/use these new features:
+
+  inactive, err := pcap.NewInactiveHandle(deviceName)
+  if err != nil {
+    log.Fatal(err)
+  }
+  defer inactive.CleanUp()
+
+  // Call various functions on inactive to set it up the way you'd like:
+  if err = inactive.SetTimeout(time.Minute); err != nil {
+    log.Fatal(err)
+  } else if err = inactive.SetTimestampSource("foo"); err != nil {
+    log.Fatal(err)
+  }
+
+  // Finally, create the actual handle by calling Activate:
+  handle, err := inactive.Activate()  // after this, inactive is no longer valid
+  if err != nil {
+    log.Fatal(err)
+  }
+  defer handle.Close()
+
+  // Now use your handle as you see fit.
+
+PCAP Timeouts
+
+pcap.OpenLive and pcap.SetTimeout both take timeouts.
+If you don't care about timeouts, just pass in BlockForever,
+which should do what you expect with minimal fuss.
+
+A timeout of 0 is not recommended.  Some platforms, like Macs
+(http://www.manpages.info/macosx/pcap.3.html) say:
+  The read timeout is used to arrange that the read not necessarily return
+  immediately when a packet is seen, but that it wait for some amount of time
+  to allow more packets to arrive and to read multiple packets from the OS
+  kernel in one operation.
+This means that if you only capture one packet, the kernel might decide to wait
+'timeout' for more packets to batch with it before returning.  A timeout of
+0, then, means 'wait forever for more packets', which is... not good.
+
+To get around this, we've introduced the following behavior:  if a negative
+timeout is passed in, we set the positive timeout in the handle, then loop
+internally in ReadPacketData/ZeroCopyReadPacketData when we see timeout
+errors.
+
+PCAP File Writing
+
+This package does not implement PCAP file writing.  However, gopacket/pcapgo
+does!  Look there if you'd like to write PCAP files.
+
+Note For Windows Users
+
+gopacket can use winpcap or npcap. If both are installed at the same time,
+npcap is preferred. Make sure the right windows service is loaded (npcap for npcap
+and npf for winpcap).
+*/
+package pcap
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)
+}
diff --git a/vendor/github.com/google/gopacket/pcap/pcap_unix.go b/vendor/github.com/google/gopacket/pcap/pcap_unix.go
new file mode 100644
index 0000000..4d6a4fb
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/pcap_unix.go
@@ -0,0 +1,709 @@
+// 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.
+//
+// +build !windows
+
+package pcap
+
+import (
+	"errors"
+	"os"
+	"sync"
+	"syscall"
+	"time"
+	"unsafe"
+
+	"github.com/google/gopacket"
+
+	"github.com/google/gopacket/layers"
+)
+
+/*
+#cgo solaris LDFLAGS: -L /opt/local/lib -lpcap
+#cgo linux LDFLAGS: -lpcap
+#cgo dragonfly LDFLAGS: -lpcap
+#cgo freebsd LDFLAGS: -lpcap
+#cgo openbsd LDFLAGS: -lpcap
+#cgo netbsd LDFLAGS: -lpcap
+#cgo darwin LDFLAGS: -lpcap
+#include <stdlib.h>
+#include <pcap.h>
+#include <stdint.h>
+
+// Some old versions of pcap don't define this constant.
+#ifndef PCAP_NETMASK_UNKNOWN
+#define PCAP_NETMASK_UNKNOWN 0xffffffff
+#endif
+
+// libpcap doesn't actually export its version in a #define-guardable way,
+// so we have to use other defined things to differentiate versions.
+// We assume at least libpcap v1.1 at the moment.
+// See http://upstream-tracker.org/versions/libpcap.html
+
+#ifndef PCAP_ERROR_TSTAMP_PRECISION_NOTSUP  // < v1.5
+#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12
+
+int pcap_set_immediate_mode(pcap_t *p, int mode) {
+  return PCAP_ERROR;
+}
+
+//  libpcap version < v1.5 doesn't have timestamp precision (everything is microsecond)
+//
+//  This means *_tstamp_* functions and macros are missing. Therefore, we emulate these
+//  functions here and pretend the setting the precision works. This is actually the way
+//  the pcap_open_offline_with_tstamp_precision works, because it doesn't return an error
+//  if it was not possible to set the precision, which depends on support by the given file.
+//  => The rest of the functions always pretend as if they could set nano precision and
+//  verify the actual precision with pcap_get_tstamp_precision, which is emulated for <v1.5
+//  to always return micro resolution.
+
+#define PCAP_TSTAMP_PRECISION_MICRO	0
+#define PCAP_TSTAMP_PRECISION_NANO	1
+
+pcap_t *pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
+  char *errbuf) {
+  return pcap_open_offline(fname, errbuf);
+}
+
+pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
+  char *errbuf) {
+  return pcap_fopen_offline(fp, errbuf);
+}
+
+int pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision) {
+  if (tstamp_precision == PCAP_TSTAMP_PRECISION_MICRO)
+    return 0;
+  return PCAP_ERROR_TSTAMP_PRECISION_NOTSUP;
+}
+
+int pcap_get_tstamp_precision(pcap_t *p) {
+  return PCAP_TSTAMP_PRECISION_MICRO;
+}
+
+#ifndef PCAP_TSTAMP_HOST  // < v1.2
+
+int pcap_set_tstamp_type(pcap_t* p, int t) { return -1; }
+int pcap_list_tstamp_types(pcap_t* p, int** t) { return 0; }
+void pcap_free_tstamp_types(int *tstamp_types) {}
+const char* pcap_tstamp_type_val_to_name(int t) {
+	return "pcap timestamp types not supported";
+}
+int pcap_tstamp_type_name_to_val(const char* t) {
+	return PCAP_ERROR;
+}
+
+#endif  // < v1.2
+#endif  // < v1.5
+
+#ifndef PCAP_ERROR_PROMISC_PERM_DENIED
+#define PCAP_ERROR_PROMISC_PERM_DENIED -11
+#endif
+
+// Windows, Macs, and Linux all use different time types.  Joy.
+#ifdef __APPLE__
+#define gopacket_time_secs_t __darwin_time_t
+#define gopacket_time_usecs_t __darwin_suseconds_t
+#elif __ANDROID__
+#define gopacket_time_secs_t __kernel_time_t
+#define gopacket_time_usecs_t __kernel_suseconds_t
+#elif __GLIBC__
+#define gopacket_time_secs_t __time_t
+#define gopacket_time_usecs_t __suseconds_t
+#else  // Some form of linux/bsd/etc...
+#include <sys/param.h>
+#ifdef __OpenBSD__
+#define gopacket_time_secs_t u_int32_t
+#define gopacket_time_usecs_t u_int32_t
+#else
+#define gopacket_time_secs_t time_t
+#define gopacket_time_usecs_t suseconds_t
+#endif
+#endif
+
+// The things we do to avoid pointers escaping to the heap...
+// According to https://github.com/the-tcpdump-group/libpcap/blob/1131a7c26c6f4d4772e4a2beeaf7212f4dea74ac/pcap.c#L398-L406 ,
+// the return value of pcap_next_ex could be greater than 1 for success.
+// Let's just make it 1 if it comes bigger than 1.
+int pcap_next_ex_escaping(pcap_t *p, uintptr_t pkt_hdr, uintptr_t pkt_data) {
+  int ex = pcap_next_ex(p, (struct pcap_pkthdr**)(pkt_hdr), (const u_char**)(pkt_data));
+  if (ex > 1) {
+    ex = 1;
+  }
+  return ex;
+}
+
+int pcap_offline_filter_escaping(struct bpf_program *fp, uintptr_t pkt_hdr, uintptr_t pkt) {
+	return pcap_offline_filter(fp, (struct pcap_pkthdr*)(pkt_hdr), (const u_char*)(pkt));
+}
+
+// pcap_wait returns when the next packet is available or the timeout expires.
+// Since it uses pcap_get_selectable_fd, it will not work in Windows.
+int pcap_wait(pcap_t *p, int usec) {
+	fd_set fds;
+	int fd;
+	struct timeval tv;
+
+	fd = pcap_get_selectable_fd(p);
+	if(fd < 0) {
+		return fd;
+	}
+
+	FD_ZERO(&fds);
+	FD_SET(fd, &fds);
+
+	tv.tv_sec = 0;
+	tv.tv_usec = usec;
+
+	if(usec != 0) {
+		return select(fd+1, &fds, NULL, NULL, &tv);
+	}
+
+	// block indefinitely if no timeout provided
+	return select(fd+1, &fds, NULL, NULL, NULL);
+}
+
+*/
+import "C"
+
+const errorBufferSize = C.PCAP_ERRBUF_SIZE
+
+const (
+	pcapErrorNotActivated    = C.PCAP_ERROR_NOT_ACTIVATED
+	pcapErrorActivated       = C.PCAP_ERROR_ACTIVATED
+	pcapWarningPromisc       = C.PCAP_WARNING_PROMISC_NOTSUP
+	pcapErrorNoSuchDevice    = C.PCAP_ERROR_NO_SUCH_DEVICE
+	pcapErrorDenied          = C.PCAP_ERROR_PERM_DENIED
+	pcapErrorNotUp           = C.PCAP_ERROR_IFACE_NOT_UP
+	pcapWarning              = C.PCAP_WARNING
+	pcapDIN                  = C.PCAP_D_IN
+	pcapDOUT                 = C.PCAP_D_OUT
+	pcapDINOUT               = C.PCAP_D_INOUT
+	pcapNetmaskUnknown       = C.PCAP_NETMASK_UNKNOWN
+	pcapTstampPrecisionMicro = C.PCAP_TSTAMP_PRECISION_MICRO
+	pcapTstampPrecisionNano  = C.PCAP_TSTAMP_PRECISION_NANO
+)
+
+type pcapPkthdr C.struct_pcap_pkthdr
+type pcapTPtr *C.struct_pcap
+type pcapBpfProgram C.struct_bpf_program
+
+func (h *pcapPkthdr) getSec() int64 {
+	return int64(h.ts.tv_sec)
+}
+
+func (h *pcapPkthdr) getUsec() int64 {
+	return int64(h.ts.tv_usec)
+}
+
+func (h *pcapPkthdr) getLen() int {
+	return int(h.len)
+}
+
+func (h *pcapPkthdr) getCaplen() int {
+	return int(h.caplen)
+}
+
+func pcapGetTstampPrecision(cptr pcapTPtr) int {
+	return int(C.pcap_get_tstamp_precision(cptr))
+}
+
+func pcapSetTstampPrecision(cptr pcapTPtr, precision int) error {
+	ret := C.pcap_set_tstamp_precision(cptr, C.int(precision))
+	if ret < 0 {
+		return errors.New(C.GoString(C.pcap_geterr(cptr)))
+	}
+	return nil
+}
+
+func statusError(status C.int) error {
+	return errors.New(C.GoString(C.pcap_statustostr(status)))
+}
+
+func pcapOpenLive(device string, snaplen int, pro int, timeout int) (*Handle, error) {
+	buf := (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(buf))
+
+	dev := C.CString(device)
+	defer C.free(unsafe.Pointer(dev))
+
+	cptr := C.pcap_open_live(dev, C.int(snaplen), C.int(pro), C.int(timeout), buf)
+	if cptr == nil {
+		return nil, errors.New(C.GoString(buf))
+	}
+	return &Handle{cptr: cptr}, nil
+}
+
+func openOffline(file string) (handle *Handle, err error) {
+	buf := (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(buf))
+	cf := C.CString(file)
+	defer C.free(unsafe.Pointer(cf))
+
+	cptr := C.pcap_open_offline_with_tstamp_precision(cf, C.PCAP_TSTAMP_PRECISION_NANO, buf)
+	if cptr == nil {
+		return nil, errors.New(C.GoString(buf))
+	}
+	return &Handle{cptr: cptr}, nil
+}
+
+func (p *Handle) pcapClose() {
+	if p.cptr != nil {
+		C.pcap_close(p.cptr)
+	}
+	p.cptr = nil
+}
+
+func (p *Handle) pcapGeterr() error {
+	return errors.New(C.GoString(C.pcap_geterr(p.cptr)))
+}
+
+func (p *Handle) pcapStats() (*Stats, error) {
+	var cstats C.struct_pcap_stat
+	if C.pcap_stats(p.cptr, &cstats) < 0 {
+		return nil, p.pcapGeterr()
+	}
+	return &Stats{
+		PacketsReceived:  int(cstats.ps_recv),
+		PacketsDropped:   int(cstats.ps_drop),
+		PacketsIfDropped: int(cstats.ps_ifdrop),
+	}, nil
+}
+
+// for libpcap < 1.8 pcap_compile is NOT thread-safe, so protect it.
+var pcapCompileMu sync.Mutex
+
+func (p *Handle) pcapCompile(expr string, maskp uint32) (pcapBpfProgram, error) {
+	var bpf pcapBpfProgram
+	cexpr := C.CString(expr)
+	defer C.free(unsafe.Pointer(cexpr))
+
+	pcapCompileMu.Lock()
+	defer pcapCompileMu.Unlock()
+	if C.pcap_compile(p.cptr, (*C.struct_bpf_program)(&bpf), cexpr, 1, C.bpf_u_int32(maskp)) < 0 {
+		return bpf, p.pcapGeterr()
+	}
+	return bpf, nil
+}
+
+func (p pcapBpfProgram) free() {
+	C.pcap_freecode((*C.struct_bpf_program)(&p))
+}
+
+func (p pcapBpfProgram) toBPFInstruction() []BPFInstruction {
+	bpfInsn := (*[bpfInstructionBufferSize]C.struct_bpf_insn)(unsafe.Pointer(p.bf_insns))[0:p.bf_len:p.bf_len]
+	bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn))
+
+	for i, v := range bpfInsn {
+		bpfInstruction[i].Code = uint16(v.code)
+		bpfInstruction[i].Jt = uint8(v.jt)
+		bpfInstruction[i].Jf = uint8(v.jf)
+		bpfInstruction[i].K = uint32(v.k)
+	}
+	return bpfInstruction
+}
+
+func pcapBpfProgramFromInstructions(bpfInstructions []BPFInstruction) pcapBpfProgram {
+	var bpf pcapBpfProgram
+	bpf.bf_len = C.u_int(len(bpfInstructions))
+	cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0])))
+	gbpfInsns := (*[bpfInstructionBufferSize]C.struct_bpf_insn)(cbpfInsns)
+
+	for i, v := range bpfInstructions {
+		gbpfInsns[i].code = C.u_short(v.Code)
+		gbpfInsns[i].jt = C.u_char(v.Jt)
+		gbpfInsns[i].jf = C.u_char(v.Jf)
+		gbpfInsns[i].k = C.bpf_u_int32(v.K)
+	}
+
+	bpf.bf_insns = (*C.struct_bpf_insn)(cbpfInsns)
+	return bpf
+}
+
+func pcapLookupnet(device string) (netp, maskp uint32, err error) {
+	errorBuf := (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(errorBuf))
+	dev := C.CString(device)
+	defer C.free(unsafe.Pointer(dev))
+	if C.pcap_lookupnet(
+		dev,
+		(*C.bpf_u_int32)(unsafe.Pointer(&netp)),
+		(*C.bpf_u_int32)(unsafe.Pointer(&maskp)),
+		errorBuf,
+	) < 0 {
+		return 0, 0, errors.New(C.GoString(errorBuf))
+		// We can't lookup the network, but that could be because the interface
+		// doesn't have an IPv4.
+	}
+	return
+}
+
+func (b *BPF) pcapOfflineFilter(ci gopacket.CaptureInfo, data []byte) bool {
+	hdr := (*C.struct_pcap_pkthdr)(&b.hdr)
+	hdr.ts.tv_sec = C.gopacket_time_secs_t(ci.Timestamp.Unix())
+	hdr.ts.tv_usec = C.gopacket_time_usecs_t(ci.Timestamp.Nanosecond() / 1000)
+	hdr.caplen = C.bpf_u_int32(len(data)) // Trust actual length over ci.Length.
+	hdr.len = C.bpf_u_int32(ci.Length)
+	dataptr := (*C.u_char)(unsafe.Pointer(&data[0]))
+	return C.pcap_offline_filter_escaping((*C.struct_bpf_program)(&b.bpf),
+		C.uintptr_t(uintptr(unsafe.Pointer(hdr))),
+		C.uintptr_t(uintptr(unsafe.Pointer(dataptr)))) != 0
+}
+
+func (p *Handle) pcapSetfilter(bpf pcapBpfProgram) error {
+	if C.pcap_setfilter(p.cptr, (*C.struct_bpf_program)(&bpf)) < 0 {
+		return p.pcapGeterr()
+	}
+	return nil
+}
+
+func (p *Handle) pcapListDatalinks() (datalinks []Datalink, err error) {
+	var dltbuf *C.int
+
+	n := int(C.pcap_list_datalinks(p.cptr, &dltbuf))
+	if n < 0 {
+		return nil, p.pcapGeterr()
+	}
+
+	defer C.pcap_free_datalinks(dltbuf)
+
+	datalinks = make([]Datalink, n)
+
+	dltArray := (*[1 << 28]C.int)(unsafe.Pointer(dltbuf))
+
+	for i := 0; i < n; i++ {
+		datalinks[i].Name = pcapDatalinkValToName(int((*dltArray)[i]))
+		datalinks[i].Description = pcapDatalinkValToDescription(int((*dltArray)[i]))
+	}
+
+	return datalinks, nil
+}
+
+func pcapOpenDead(linkType layers.LinkType, captureLength int) (*Handle, error) {
+	cptr := C.pcap_open_dead(C.int(linkType), C.int(captureLength))
+	if cptr == nil {
+		return nil, errors.New("error opening dead capture")
+	}
+
+	return &Handle{cptr: cptr}, nil
+}
+
+func (p *Handle) pcapNextPacketEx() NextError {
+	// This horrible magic allows us to pass a ptr-to-ptr to pcap_next_ex
+	// without causing that ptr-to-ptr to itself be allocated on the heap.
+	// Since Handle itself survives through the duration of the pcap_next_ex
+	// call, this should be perfectly safe for GC stuff, etc.
+
+	return NextError(C.pcap_next_ex_escaping(p.cptr, C.uintptr_t(uintptr(unsafe.Pointer(&p.pkthdr))), C.uintptr_t(uintptr(unsafe.Pointer(&p.bufptr)))))
+}
+
+func (p *Handle) pcapDatalink() layers.LinkType {
+	return layers.LinkType(C.pcap_datalink(p.cptr))
+}
+
+func (p *Handle) pcapSetDatalink(dlt layers.LinkType) error {
+	if C.pcap_set_datalink(p.cptr, C.int(dlt)) < 0 {
+		return p.pcapGeterr()
+	}
+	return nil
+}
+
+func pcapDatalinkValToName(dlt int) string {
+	return C.GoString(C.pcap_datalink_val_to_name(C.int(dlt)))
+}
+
+func pcapDatalinkValToDescription(dlt int) string {
+	return C.GoString(C.pcap_datalink_val_to_description(C.int(dlt)))
+}
+
+func pcapDatalinkNameToVal(name string) int {
+	cptr := C.CString(name)
+	defer C.free(unsafe.Pointer(cptr))
+	return int(C.pcap_datalink_name_to_val(cptr))
+}
+
+func pcapLibVersion() string {
+	return C.GoString(C.pcap_lib_version())
+}
+
+func (p *Handle) isOpen() bool {
+	return p.cptr != nil
+}
+
+type pcapDevices struct {
+	all, cur *C.pcap_if_t
+}
+
+func (p pcapDevices) free() {
+	C.pcap_freealldevs((*C.pcap_if_t)(p.all))
+}
+
+func (p *pcapDevices) next() bool {
+	if p.cur == nil {
+		p.cur = p.all
+		if p.cur == nil {
+			return false
+		}
+		return true
+	}
+	if p.cur.next == nil {
+		return false
+	}
+	p.cur = p.cur.next
+	return true
+}
+
+func (p pcapDevices) name() string {
+	return C.GoString(p.cur.name)
+}
+
+func (p pcapDevices) description() string {
+	return C.GoString(p.cur.description)
+}
+
+func (p pcapDevices) flags() uint32 {
+	return uint32(p.cur.flags)
+}
+
+type pcapAddresses struct {
+	all, cur *C.pcap_addr_t
+}
+
+func (p *pcapAddresses) next() bool {
+	if p.cur == nil {
+		p.cur = p.all
+		if p.cur == nil {
+			return false
+		}
+		return true
+	}
+	if p.cur.next == nil {
+		return false
+	}
+	p.cur = p.cur.next
+	return true
+}
+
+func (p pcapAddresses) addr() *syscall.RawSockaddr {
+	return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.addr))
+}
+
+func (p pcapAddresses) netmask() *syscall.RawSockaddr {
+	return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.netmask))
+}
+
+func (p pcapAddresses) broadaddr() *syscall.RawSockaddr {
+	return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.broadaddr))
+}
+
+func (p pcapAddresses) dstaddr() *syscall.RawSockaddr {
+	return (*syscall.RawSockaddr)(unsafe.Pointer(p.cur.dstaddr))
+}
+
+func (p pcapDevices) addresses() pcapAddresses {
+	return pcapAddresses{all: p.cur.addresses}
+}
+
+func pcapFindAllDevs() (pcapDevices, error) {
+	var buf *C.char
+	buf = (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(buf))
+	var alldevsp pcapDevices
+
+	if C.pcap_findalldevs((**C.pcap_if_t)(&alldevsp.all), buf) < 0 {
+		return pcapDevices{}, errors.New(C.GoString(buf))
+	}
+	return alldevsp, nil
+}
+
+func (p *Handle) pcapSendpacket(data []byte) error {
+	if C.pcap_sendpacket(p.cptr, (*C.u_char)(&data[0]), (C.int)(len(data))) < 0 {
+		return p.pcapGeterr()
+	}
+	return nil
+}
+
+func (p *Handle) pcapSetdirection(direction Direction) error {
+	if status := C.pcap_setdirection(p.cptr, (C.pcap_direction_t)(direction)); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *Handle) pcapSnapshot() int {
+	return int(C.pcap_snapshot(p.cptr))
+}
+
+func (t TimestampSource) pcapTstampTypeValToName() string {
+	return C.GoString(C.pcap_tstamp_type_val_to_name(C.int(t)))
+}
+
+func pcapTstampTypeNameToVal(s string) (TimestampSource, error) {
+	cs := C.CString(s)
+	defer C.free(unsafe.Pointer(cs))
+	t := C.pcap_tstamp_type_name_to_val(cs)
+	if t < 0 {
+		return 0, statusError(t)
+	}
+	return TimestampSource(t), nil
+}
+
+func (p *InactiveHandle) pcapGeterr() error {
+	return errors.New(C.GoString(C.pcap_geterr(p.cptr)))
+}
+
+func (p *InactiveHandle) pcapActivate() (*Handle, activateError) {
+	ret := activateError(C.pcap_activate(p.cptr))
+	if ret != aeNoError {
+		return nil, ret
+	}
+	h := &Handle{
+		cptr: p.cptr,
+	}
+	p.cptr = nil
+	return h, ret
+}
+
+func (p *InactiveHandle) pcapClose() {
+	if p.cptr != nil {
+		C.pcap_close(p.cptr)
+	}
+}
+
+func pcapCreate(device string) (*InactiveHandle, error) {
+	buf := (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(buf))
+	dev := C.CString(device)
+	defer C.free(unsafe.Pointer(dev))
+
+	cptr := C.pcap_create(dev, buf)
+	if cptr == nil {
+		return nil, errors.New(C.GoString(buf))
+	}
+	return &InactiveHandle{cptr: cptr}, nil
+}
+
+func (p *InactiveHandle) pcapSetSnaplen(snaplen int) error {
+	if status := C.pcap_set_snaplen(p.cptr, C.int(snaplen)); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetPromisc(promisc bool) error {
+	var pro C.int
+	if promisc {
+		pro = 1
+	}
+	if status := C.pcap_set_promisc(p.cptr, pro); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetTimeout(timeout time.Duration) error {
+	if status := C.pcap_set_timeout(p.cptr, C.int(timeoutMillis(timeout))); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapListTstampTypes() (out []TimestampSource) {
+	var types *C.int
+	n := int(C.pcap_list_tstamp_types(p.cptr, &types))
+	if n < 0 {
+		return // public interface doesn't have error :(
+	}
+	defer C.pcap_free_tstamp_types(types)
+	typesArray := (*[1 << 28]C.int)(unsafe.Pointer(types))
+	for i := 0; i < n; i++ {
+		out = append(out, TimestampSource((*typesArray)[i]))
+	}
+	return
+}
+
+func (p *InactiveHandle) pcapSetTstampType(t TimestampSource) error {
+	if status := C.pcap_set_tstamp_type(p.cptr, C.int(t)); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetRfmon(monitor bool) error {
+	var mon C.int
+	if monitor {
+		mon = 1
+	}
+	switch canset := C.pcap_can_set_rfmon(p.cptr); canset {
+	case 0:
+		return CannotSetRFMon
+	case 1:
+		// success
+	default:
+		return statusError(canset)
+	}
+	if status := C.pcap_set_rfmon(p.cptr, mon); status != 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetBufferSize(bufferSize int) error {
+	if status := C.pcap_set_buffer_size(p.cptr, C.int(bufferSize)); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetImmediateMode(mode bool) error {
+	var md C.int
+	if mode {
+		md = 1
+	}
+	if status := C.pcap_set_immediate_mode(p.cptr, md); status < 0 {
+		return statusError(status)
+	}
+	return nil
+}
+
+func (p *Handle) setNonBlocking() error {
+	buf := (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(buf))
+
+	// Change the device to non-blocking, we'll use pcap_wait to wait until the
+	// handle is ready to read.
+	if v := C.pcap_setnonblock(p.cptr, 1, buf); v < -1 {
+		return errors.New(C.GoString(buf))
+	}
+
+	return nil
+}
+
+// waitForPacket waits for a packet or for the timeout to expire.
+func (p *Handle) waitForPacket() {
+	// need to wait less than the read timeout according to pcap documentation.
+	// timeoutMillis rounds up to at least one millisecond so we can safely
+	// subtract up to a millisecond.
+	usec := timeoutMillis(p.timeout) * 1000
+	usec -= 100
+
+	C.pcap_wait(p.cptr, C.int(usec))
+}
+
+// openOfflineFile returns contents of input file as a *Handle.
+func openOfflineFile(file *os.File) (handle *Handle, err error) {
+	buf := (*C.char)(C.calloc(errorBufferSize, 1))
+	defer C.free(unsafe.Pointer(buf))
+	cmode := C.CString("rb")
+	defer C.free(unsafe.Pointer(cmode))
+	cf := C.fdopen(C.int(file.Fd()), cmode)
+
+	cptr := C.pcap_fopen_offline_with_tstamp_precision(cf, C.PCAP_TSTAMP_PRECISION_NANO, buf)
+	if cptr == nil {
+		return nil, errors.New(C.GoString(buf))
+	}
+	return &Handle{cptr: cptr}, nil
+}
diff --git a/vendor/github.com/google/gopacket/pcap/pcap_windows.go b/vendor/github.com/google/gopacket/pcap/pcap_windows.go
new file mode 100644
index 0000000..0a53338
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/pcap_windows.go
@@ -0,0 +1,885 @@
+// 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"
+	"os"
+	"runtime"
+	"sync"
+	"syscall"
+	"time"
+	"unsafe"
+
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+)
+
+var pcapLoaded = false
+
+const npcapPath = "\\Npcap"
+
+func initDllPath(kernel32 syscall.Handle) {
+	setDllDirectory, err := syscall.GetProcAddress(kernel32, "SetDllDirectoryA")
+	if err != nil {
+		// we can't do anything since SetDllDirectoryA is missing - fall back to use first wpcap.dll we encounter
+		return
+	}
+	getSystemDirectory, err := syscall.GetProcAddress(kernel32, "GetSystemDirectoryA")
+	if err != nil {
+		// we can't do anything since SetDllDirectoryA is missing - fall back to use first wpcap.dll we encounter
+		return
+	}
+	buf := make([]byte, 4096)
+	r, _, _ := syscall.Syscall(getSystemDirectory, 2, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
+	if r == 0 || r > 4096-uintptr(len(npcapPath))-1 {
+		// we can't do anything since SetDllDirectoryA is missing - fall back to use first wpcap.dll we encounter
+		return
+	}
+	copy(buf[r:], npcapPath)
+	_, _, _ = syscall.Syscall(setDllDirectory, 1, uintptr(unsafe.Pointer(&buf[0])), 0, 0)
+	// ignore errors here - we just fallback to load wpcap.dll from default locations
+}
+
+// loadedDllPath will hold the full pathname of the loaded wpcap.dll after init if possible
+var loadedDllPath = "wpcap.dll"
+
+func initLoadedDllPath(kernel32 syscall.Handle) {
+	getModuleFileName, err := syscall.GetProcAddress(kernel32, "GetModuleFileNameA")
+	if err != nil {
+		// we can't get the filename of the loaded module in this case - just leave default of wpcap.dll
+		return
+	}
+	buf := make([]byte, 4096)
+	r, _, _ := syscall.Syscall(getModuleFileName, 3, uintptr(wpcapHandle), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
+	if r == 0 {
+		// we can't get the filename of the loaded module in this case - just leave default of wpcap.dll
+		return
+	}
+	loadedDllPath = string(buf[:int(r)])
+}
+
+func mustLoad(fun string) uintptr {
+	addr, err := syscall.GetProcAddress(wpcapHandle, fun)
+	if err != nil {
+		panic(fmt.Sprintf("Couldn't load function %s from %s", fun, loadedDllPath))
+	}
+	return addr
+}
+
+func mightLoad(fun string) uintptr {
+	addr, err := syscall.GetProcAddress(wpcapHandle, fun)
+	if err != nil {
+		return 0
+	}
+	return addr
+}
+
+func byteSliceToString(bval []byte) string {
+	for i := range bval {
+		if bval[i] == 0 {
+			return string(bval[:i])
+		}
+	}
+	return string(bval[:])
+}
+
+// bytePtrToString returns a string copied from pointer to a null terminated byte array
+// WARNING: ONLY SAFE WITH IF r POINTS TO C MEMORY!
+// govet will complain about this function for the reason stated above
+func bytePtrToString(r uintptr) string {
+	if r == 0 {
+		return ""
+	}
+	bval := (*[1 << 30]byte)(unsafe.Pointer(r))
+	return byteSliceToString(bval[:])
+}
+
+var wpcapHandle syscall.Handle
+var msvcrtHandle syscall.Handle
+var (
+	callocPtr,
+	pcapStrerrorPtr,
+	pcapStatustostrPtr,
+	pcapOpenLivePtr,
+	pcapOpenOfflinePtr,
+	pcapClosePtr,
+	pcapGeterrPtr,
+	pcapStatsPtr,
+	pcapCompilePtr,
+	pcapFreecodePtr,
+	pcapLookupnetPtr,
+	pcapOfflineFilterPtr,
+	pcapSetfilterPtr,
+	pcapListDatalinksPtr,
+	pcapFreeDatalinksPtr,
+	pcapDatalinkValToNamePtr,
+	pcapDatalinkValToDescriptionPtr,
+	pcapOpenDeadPtr,
+	pcapNextExPtr,
+	pcapDatalinkPtr,
+	pcapSetDatalinkPtr,
+	pcapDatalinkNameToValPtr,
+	pcapLibVersionPtr,
+	pcapFreealldevsPtr,
+	pcapFindalldevsPtr,
+	pcapSendpacketPtr,
+	pcapSetdirectionPtr,
+	pcapSnapshotPtr,
+	pcapTstampTypeValToNamePtr,
+	pcapTstampTypeNameToValPtr,
+	pcapListTstampTypesPtr,
+	pcapFreeTstampTypesPtr,
+	pcapSetTstampTypePtr,
+	pcapGetTstampPrecisionPtr,
+	pcapSetTstampPrecisionPtr,
+	pcapOpenOfflineWithTstampPrecisionPtr,
+	pcapHOpenOfflineWithTstampPrecisionPtr,
+	pcapActivatePtr,
+	pcapCreatePtr,
+	pcapSetSnaplenPtr,
+	pcapSetPromiscPtr,
+	pcapSetTimeoutPtr,
+	pcapCanSetRfmonPtr,
+	pcapSetRfmonPtr,
+	pcapSetBufferSizePtr,
+	pcapSetImmediateModePtr,
+	pcapHopenOfflinePtr uintptr
+)
+
+func init() {
+	LoadWinPCAP()
+}
+
+// LoadWinPCAP attempts to dynamically load the wpcap DLL and resolve necessary functions
+func LoadWinPCAP() error {
+	if pcapLoaded {
+		return nil
+	}
+
+	kernel32, err := syscall.LoadLibrary("kernel32.dll")
+	if err != nil {
+		return fmt.Errorf("couldn't load kernel32.dll")
+	}
+	defer syscall.FreeLibrary(kernel32)
+
+	initDllPath(kernel32)
+
+	wpcapHandle, err = syscall.LoadLibrary("wpcap.dll")
+	if err != nil {
+		return fmt.Errorf("couldn't load wpcap.dll")
+	}
+	initLoadedDllPath(kernel32)
+	msvcrtHandle, err = syscall.LoadLibrary("msvcrt.dll")
+	if err != nil {
+		return fmt.Errorf("couldn't load msvcrt.dll")
+	}
+	callocPtr, err = syscall.GetProcAddress(msvcrtHandle, "calloc")
+	if err != nil {
+		return fmt.Errorf("couldn't get calloc function")
+	}
+
+	pcapStrerrorPtr = mustLoad("pcap_strerror")
+	pcapStatustostrPtr = mightLoad("pcap_statustostr") // not available on winpcap
+	pcapOpenLivePtr = mustLoad("pcap_open_live")
+	pcapOpenOfflinePtr = mustLoad("pcap_open_offline")
+	pcapClosePtr = mustLoad("pcap_close")
+	pcapGeterrPtr = mustLoad("pcap_geterr")
+	pcapStatsPtr = mustLoad("pcap_stats")
+	pcapCompilePtr = mustLoad("pcap_compile")
+	pcapFreecodePtr = mustLoad("pcap_freecode")
+	pcapLookupnetPtr = mustLoad("pcap_lookupnet")
+	pcapOfflineFilterPtr = mustLoad("pcap_offline_filter")
+	pcapSetfilterPtr = mustLoad("pcap_setfilter")
+	pcapListDatalinksPtr = mustLoad("pcap_list_datalinks")
+	pcapFreeDatalinksPtr = mustLoad("pcap_free_datalinks")
+	pcapDatalinkValToNamePtr = mustLoad("pcap_datalink_val_to_name")
+	pcapDatalinkValToDescriptionPtr = mustLoad("pcap_datalink_val_to_description")
+	pcapOpenDeadPtr = mustLoad("pcap_open_dead")
+	pcapNextExPtr = mustLoad("pcap_next_ex")
+	pcapDatalinkPtr = mustLoad("pcap_datalink")
+	pcapSetDatalinkPtr = mustLoad("pcap_set_datalink")
+	pcapDatalinkNameToValPtr = mustLoad("pcap_datalink_name_to_val")
+	pcapLibVersionPtr = mustLoad("pcap_lib_version")
+	pcapFreealldevsPtr = mustLoad("pcap_freealldevs")
+	pcapFindalldevsPtr = mustLoad("pcap_findalldevs")
+	pcapSendpacketPtr = mustLoad("pcap_sendpacket")
+	pcapSetdirectionPtr = mustLoad("pcap_setdirection")
+	pcapSnapshotPtr = mustLoad("pcap_snapshot")
+	//libpcap <1.2 doesn't have pcap_*_tstamp_* functions
+	pcapTstampTypeValToNamePtr = mightLoad("pcap_tstamp_type_val_to_name")
+	pcapTstampTypeNameToValPtr = mightLoad("pcap_tstamp_type_name_to_val")
+	pcapListTstampTypesPtr = mightLoad("pcap_list_tstamp_types")
+	pcapFreeTstampTypesPtr = mightLoad("pcap_free_tstamp_types")
+	pcapSetTstampTypePtr = mightLoad("pcap_set_tstamp_type")
+	pcapGetTstampPrecisionPtr = mightLoad("pcap_get_tstamp_precision")
+	pcapSetTstampPrecisionPtr = mightLoad("pcap_set_tstamp_precision")
+	pcapOpenOfflineWithTstampPrecisionPtr = mightLoad("pcap_open_offline_with_tstamp_precision")
+	pcapHOpenOfflineWithTstampPrecisionPtr = mightLoad("pcap_hopen_offline_with_tstamp_precision")
+	pcapActivatePtr = mustLoad("pcap_activate")
+	pcapCreatePtr = mustLoad("pcap_create")
+	pcapSetSnaplenPtr = mustLoad("pcap_set_snaplen")
+	pcapSetPromiscPtr = mustLoad("pcap_set_promisc")
+	pcapSetTimeoutPtr = mustLoad("pcap_set_timeout")
+	//winpcap does not support rfmon
+	pcapCanSetRfmonPtr = mightLoad("pcap_can_set_rfmon")
+	pcapSetRfmonPtr = mightLoad("pcap_set_rfmon")
+	pcapSetBufferSizePtr = mustLoad("pcap_set_buffer_size")
+	//libpcap <1.5 does not have pcap_set_immediate_mode
+	pcapSetImmediateModePtr = mightLoad("pcap_set_immediate_mode")
+	pcapHopenOfflinePtr = mustLoad("pcap_hopen_offline")
+
+	pcapLoaded = true
+	return nil
+}
+
+func (h *pcapPkthdr) getSec() int64 {
+	return int64(h.Ts.Sec)
+}
+
+func (h *pcapPkthdr) getUsec() int64 {
+	return int64(h.Ts.Usec)
+}
+
+func (h *pcapPkthdr) getLen() int {
+	return int(h.Len)
+}
+
+func (h *pcapPkthdr) getCaplen() int {
+	return int(h.Caplen)
+}
+
+func statusError(status pcapCint) error {
+	var ret uintptr
+	if pcapStatustostrPtr == 0 {
+		ret, _, _ = syscall.Syscall(pcapStrerrorPtr, 1, uintptr(status), 0, 0)
+	} else {
+		ret, _, _ = syscall.Syscall(pcapStatustostrPtr, 1, uintptr(status), 0, 0)
+	}
+	return errors.New(bytePtrToString(ret))
+}
+
+func pcapGetTstampPrecision(cptr pcapTPtr) int {
+	if pcapGetTstampPrecisionPtr == 0 {
+		return pcapTstampPrecisionMicro
+	}
+	ret, _, _ := syscall.Syscall(pcapGetTstampPrecisionPtr, 1, uintptr(cptr), 0, 0)
+	return int(pcapCint(ret))
+}
+
+func pcapSetTstampPrecision(cptr pcapTPtr, precision int) error {
+	if pcapSetTstampPrecisionPtr == 0 {
+		return errors.New("Not supported")
+	}
+	ret, _, _ := syscall.Syscall(pcapSetTstampPrecisionPtr, 2, uintptr(cptr), uintptr(precision), 0)
+	if pcapCint(ret) < 0 {
+		return errors.New("Not supported")
+	}
+	return nil
+}
+
+func pcapOpenLive(device string, snaplen int, pro int, timeout int) (*Handle, error) {
+	err := LoadWinPCAP()
+	if err != nil {
+		return nil, err
+	}
+
+	buf := make([]byte, errorBufferSize)
+	dev, err := syscall.BytePtrFromString(device)
+	if err != nil {
+		return nil, err
+	}
+
+	cptr, _, _ := syscall.Syscall6(pcapOpenLivePtr, 5, uintptr(unsafe.Pointer(dev)), uintptr(snaplen), uintptr(pro), uintptr(timeout), uintptr(unsafe.Pointer(&buf[0])), 0)
+
+	if cptr == 0 {
+		return nil, errors.New(byteSliceToString(buf))
+	}
+	return &Handle{cptr: pcapTPtr(cptr)}, nil
+}
+
+func openOffline(file string) (handle *Handle, err error) {
+	err = LoadWinPCAP()
+	if err != nil {
+		return nil, err
+	}
+
+	buf := make([]byte, errorBufferSize)
+	f, err := syscall.BytePtrFromString(file)
+	if err != nil {
+		return nil, err
+	}
+
+	var cptr uintptr
+	if pcapOpenOfflineWithTstampPrecisionPtr == 0 {
+		cptr, _, _ = syscall.Syscall(pcapOpenOfflinePtr, 2, uintptr(unsafe.Pointer(f)), uintptr(unsafe.Pointer(&buf[0])), 0)
+	} else {
+		cptr, _, _ = syscall.Syscall(pcapOpenOfflineWithTstampPrecisionPtr, 3, uintptr(unsafe.Pointer(f)), uintptr(pcapTstampPrecisionNano), uintptr(unsafe.Pointer(&buf[0])))
+	}
+
+	if cptr == 0 {
+		return nil, errors.New(byteSliceToString(buf))
+	}
+
+	h := &Handle{cptr: pcapTPtr(cptr)}
+	return h, nil
+}
+
+func (p *Handle) pcapClose() {
+	if p.cptr != 0 {
+		_, _, _ = syscall.Syscall(pcapClosePtr, 1, uintptr(p.cptr), 0, 0)
+	}
+	p.cptr = 0
+}
+
+func (p *Handle) pcapGeterr() error {
+	ret, _, _ := syscall.Syscall(pcapGeterrPtr, 1, uintptr(p.cptr), 0, 0)
+	return errors.New(bytePtrToString(ret))
+}
+
+func (p *Handle) pcapStats() (*Stats, error) {
+	var cstats pcapStats
+	ret, _, _ := syscall.Syscall(pcapStatsPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&cstats)), 0)
+	if pcapCint(ret) < 0 {
+		return nil, p.pcapGeterr()
+	}
+	return &Stats{
+		PacketsReceived:  int(cstats.Recv),
+		PacketsDropped:   int(cstats.Drop),
+		PacketsIfDropped: int(cstats.Ifdrop),
+	}, nil
+}
+
+// for libpcap < 1.8 pcap_compile is NOT thread-safe, so protect it.
+var pcapCompileMu sync.Mutex
+
+func (p *Handle) pcapCompile(expr string, maskp uint32) (pcapBpfProgram, error) {
+	var bpf pcapBpfProgram
+	cexpr, err := syscall.BytePtrFromString(expr)
+	if err != nil {
+		return pcapBpfProgram{}, err
+	}
+	pcapCompileMu.Lock()
+	defer pcapCompileMu.Unlock()
+	res, _, _ := syscall.Syscall6(pcapCompilePtr, 5, uintptr(p.cptr), uintptr(unsafe.Pointer(&bpf)), uintptr(unsafe.Pointer(cexpr)), uintptr(1), uintptr(maskp), 0)
+	if pcapCint(res) < 0 {
+		return bpf, p.pcapGeterr()
+	}
+	return bpf, nil
+}
+
+func (p pcapBpfProgram) free() {
+	_, _, _ = syscall.Syscall(pcapFreecodePtr, 1, uintptr(unsafe.Pointer(&p)), 0, 0)
+}
+
+func (p pcapBpfProgram) toBPFInstruction() []BPFInstruction {
+	bpfInsn := (*[bpfInstructionBufferSize]pcapBpfInstruction)(unsafe.Pointer(p.Insns))[0:p.Len:p.Len]
+	bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn))
+
+	for i, v := range bpfInsn {
+		bpfInstruction[i].Code = v.Code
+		bpfInstruction[i].Jt = v.Jt
+		bpfInstruction[i].Jf = v.Jf
+		bpfInstruction[i].K = v.K
+	}
+	return bpfInstruction
+}
+
+func pcapBpfProgramFromInstructions(bpfInstructions []BPFInstruction) pcapBpfProgram {
+	var bpf pcapBpfProgram
+	bpf.Len = uint32(len(bpfInstructions))
+	cbpfInsns, _, _ := syscall.Syscall(callocPtr, 2, uintptr(len(bpfInstructions)), uintptr(unsafe.Sizeof(bpfInstructions[0])), 0)
+	gbpfInsns := (*[bpfInstructionBufferSize]pcapBpfInstruction)(unsafe.Pointer(cbpfInsns))
+
+	for i, v := range bpfInstructions {
+		gbpfInsns[i].Code = v.Code
+		gbpfInsns[i].Jt = v.Jt
+		gbpfInsns[i].Jf = v.Jf
+		gbpfInsns[i].K = v.K
+	}
+
+	bpf.Insns = (*pcapBpfInstruction)(unsafe.Pointer(cbpfInsns))
+	return bpf
+}
+
+func pcapLookupnet(device string) (netp, maskp uint32, err error) {
+	err = LoadWinPCAP()
+	if err != nil {
+		return 0, 0, err
+	}
+
+	buf := make([]byte, errorBufferSize)
+	dev, err := syscall.BytePtrFromString(device)
+	if err != nil {
+		return 0, 0, err
+	}
+	e, _, _ := syscall.Syscall6(pcapLookupnetPtr, 4, uintptr(unsafe.Pointer(dev)), uintptr(unsafe.Pointer(&netp)), uintptr(unsafe.Pointer(&maskp)), uintptr(unsafe.Pointer(&buf[0])), 0, 0)
+	if pcapCint(e) < 0 {
+		return 0, 0, errors.New(byteSliceToString(buf))
+	}
+	return
+}
+
+func (b *BPF) pcapOfflineFilter(ci gopacket.CaptureInfo, data []byte) bool {
+	var hdr pcapPkthdr
+	hdr.Ts.Sec = int32(ci.Timestamp.Unix())
+	hdr.Ts.Usec = int32(ci.Timestamp.Nanosecond() / 1000)
+	hdr.Caplen = uint32(len(data)) // Trust actual length over ci.Length.
+	hdr.Len = uint32(ci.Length)
+	e, _, _ := syscall.Syscall(pcapOfflineFilterPtr, 3, uintptr(unsafe.Pointer(&b.bpf)), uintptr(unsafe.Pointer(&hdr)), uintptr(unsafe.Pointer(&data[0])))
+	return e != 0
+}
+
+func (p *Handle) pcapSetfilter(bpf pcapBpfProgram) error {
+	e, _, _ := syscall.Syscall(pcapSetfilterPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&bpf)), 0)
+	if pcapCint(e) < 0 {
+		return p.pcapGeterr()
+	}
+	return nil
+}
+
+func (p *Handle) pcapListDatalinks() (datalinks []Datalink, err error) {
+	var dltbuf *pcapCint
+	ret, _, _ := syscall.Syscall(pcapListDatalinksPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&dltbuf)), 0)
+
+	n := int(pcapCint(ret))
+
+	if n < 0 {
+		return nil, p.pcapGeterr()
+	}
+	defer syscall.Syscall(pcapFreeDatalinksPtr, 1, uintptr(unsafe.Pointer(dltbuf)), 0, 0)
+
+	datalinks = make([]Datalink, n)
+
+	dltArray := (*[1 << 28]pcapCint)(unsafe.Pointer(dltbuf))
+
+	for i := 0; i < n; i++ {
+		datalinks[i].Name = pcapDatalinkValToName(int((*dltArray)[i]))
+		datalinks[i].Description = pcapDatalinkValToDescription(int((*dltArray)[i]))
+	}
+
+	return datalinks, nil
+}
+
+func pcapOpenDead(linkType layers.LinkType, captureLength int) (*Handle, error) {
+	err := LoadWinPCAP()
+	if err != nil {
+		return nil, err
+	}
+
+	cptr, _, _ := syscall.Syscall(pcapOpenDeadPtr, 2, uintptr(linkType), uintptr(captureLength), 0)
+	if cptr == 0 {
+		return nil, errors.New("error opening dead capture")
+	}
+
+	return &Handle{cptr: pcapTPtr(cptr)}, nil
+}
+
+func (p *Handle) pcapNextPacketEx() NextError {
+	r, _, _ := syscall.Syscall(pcapNextExPtr, 3, uintptr(p.cptr), uintptr(unsafe.Pointer(&p.pkthdr)), uintptr(unsafe.Pointer(&p.bufptr)))
+	ret := pcapCint(r)
+	// According to https://github.com/the-tcpdump-group/libpcap/blob/1131a7c26c6f4d4772e4a2beeaf7212f4dea74ac/pcap.c#L398-L406 ,
+	// the return value of pcap_next_ex could be greater than 1 for success.
+	// Let's just make it 1 if it comes bigger than 1.
+	if ret > 1 {
+		ret = 1
+	}
+	return NextError(ret)
+}
+
+func (p *Handle) pcapDatalink() layers.LinkType {
+	ret, _, _ := syscall.Syscall(pcapDatalinkPtr, 1, uintptr(p.cptr), 0, 0)
+	return layers.LinkType(ret)
+}
+
+func (p *Handle) pcapSetDatalink(dlt layers.LinkType) error {
+	ret, _, _ := syscall.Syscall(pcapSetDatalinkPtr, 2, uintptr(p.cptr), uintptr(dlt), 0)
+	if pcapCint(ret) < 0 {
+		return p.pcapGeterr()
+	}
+	return nil
+}
+
+func pcapDatalinkValToName(dlt int) string {
+	err := LoadWinPCAP()
+	if err != nil {
+		panic(err)
+	}
+	ret, _, _ := syscall.Syscall(pcapDatalinkValToNamePtr, 1, uintptr(dlt), 0, 0)
+	return bytePtrToString(ret)
+}
+
+func pcapDatalinkValToDescription(dlt int) string {
+	err := LoadWinPCAP()
+	if err != nil {
+		panic(err)
+	}
+	ret, _, _ := syscall.Syscall(pcapDatalinkValToDescriptionPtr, 1, uintptr(dlt), 0, 0)
+	return bytePtrToString(ret)
+}
+
+func pcapDatalinkNameToVal(name string) int {
+	err := LoadWinPCAP()
+	if err != nil {
+		panic(err)
+	}
+	cptr, err := syscall.BytePtrFromString(name)
+	if err != nil {
+		return 0
+	}
+	ret, _, _ := syscall.Syscall(pcapDatalinkNameToValPtr, 1, uintptr(unsafe.Pointer(cptr)), 0, 0)
+	return int(pcapCint(ret))
+}
+
+func pcapLibVersion() string {
+	err := LoadWinPCAP()
+	if err != nil {
+		panic(err)
+	}
+	ret, _, _ := syscall.Syscall(pcapLibVersionPtr, 0, 0, 0, 0)
+	return bytePtrToString(ret)
+}
+
+func (p *Handle) isOpen() bool {
+	return p.cptr != 0
+}
+
+type pcapDevices struct {
+	all, cur *pcapIf
+}
+
+func (p pcapDevices) free() {
+	syscall.Syscall(pcapFreealldevsPtr, 1, uintptr(unsafe.Pointer(p.all)), 0, 0)
+}
+
+func (p *pcapDevices) next() bool {
+	if p.cur == nil {
+		p.cur = p.all
+		if p.cur == nil {
+			return false
+		}
+		return true
+	}
+	if p.cur.Next == nil {
+		return false
+	}
+	p.cur = p.cur.Next
+	return true
+}
+
+func (p pcapDevices) name() string {
+	return bytePtrToString(uintptr(unsafe.Pointer(p.cur.Name)))
+}
+
+func (p pcapDevices) description() string {
+	return bytePtrToString(uintptr(unsafe.Pointer(p.cur.Description)))
+}
+
+func (p pcapDevices) flags() uint32 {
+	return p.cur.Flags
+}
+
+type pcapAddresses struct {
+	all, cur *pcapAddr
+}
+
+func (p *pcapAddresses) next() bool {
+	if p.cur == nil {
+		p.cur = p.all
+		if p.cur == nil {
+			return false
+		}
+		return true
+	}
+	if p.cur.Next == nil {
+		return false
+	}
+	p.cur = p.cur.Next
+	return true
+}
+
+func (p pcapAddresses) addr() *syscall.RawSockaddr {
+	return p.cur.Addr
+}
+
+func (p pcapAddresses) netmask() *syscall.RawSockaddr {
+	return p.cur.Netmask
+}
+
+func (p pcapAddresses) broadaddr() *syscall.RawSockaddr {
+	return p.cur.Broadaddr
+}
+
+func (p pcapAddresses) dstaddr() *syscall.RawSockaddr {
+	return p.cur.Dstaddr
+}
+
+func (p pcapDevices) addresses() pcapAddresses {
+	return pcapAddresses{all: p.cur.Addresses}
+}
+
+func pcapFindAllDevs() (pcapDevices, error) {
+	var alldevsp pcapDevices
+	err := LoadWinPCAP()
+	if err != nil {
+		return alldevsp, err
+	}
+
+	buf := make([]byte, errorBufferSize)
+
+	ret, _, _ := syscall.Syscall(pcapFindalldevsPtr, 2, uintptr(unsafe.Pointer(&alldevsp.all)), uintptr(unsafe.Pointer(&buf[0])), 0)
+
+	if pcapCint(ret) < 0 {
+		return pcapDevices{}, errors.New(byteSliceToString(buf))
+	}
+	return alldevsp, nil
+}
+
+func (p *Handle) pcapSendpacket(data []byte) error {
+	ret, _, _ := syscall.Syscall(pcapSendpacketPtr, 3, uintptr(p.cptr), uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)))
+	if pcapCint(ret) < 0 {
+		return p.pcapGeterr()
+	}
+	return nil
+}
+
+func (p *Handle) pcapSetdirection(direction Direction) error {
+	status, _, _ := syscall.Syscall(pcapSetdirectionPtr, 2, uintptr(p.cptr), uintptr(direction), 0)
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *Handle) pcapSnapshot() int {
+	ret, _, _ := syscall.Syscall(pcapSnapshotPtr, 1, uintptr(p.cptr), 0, 0)
+	return int(pcapCint(ret))
+}
+
+func (t TimestampSource) pcapTstampTypeValToName() string {
+	err := LoadWinPCAP()
+	if err != nil {
+		return err.Error()
+	}
+
+	//libpcap <1.2 doesn't have pcap_*_tstamp_* functions
+	if pcapTstampTypeValToNamePtr == 0 {
+		return "pcap timestamp types not supported"
+	}
+	ret, _, _ := syscall.Syscall(pcapTstampTypeValToNamePtr, 1, uintptr(t), 0, 0)
+	return bytePtrToString(ret)
+}
+
+func pcapTstampTypeNameToVal(s string) (TimestampSource, error) {
+	err := LoadWinPCAP()
+	if err != nil {
+		return 0, err
+	}
+
+	//libpcap <1.2 doesn't have pcap_*_tstamp_* functions
+	if pcapTstampTypeNameToValPtr == 0 {
+		return 0, statusError(pcapCint(pcapError))
+	}
+	cs, err := syscall.BytePtrFromString(s)
+	if err != nil {
+		return 0, err
+	}
+	ret, _, _ := syscall.Syscall(pcapTstampTypeNameToValPtr, 1, uintptr(unsafe.Pointer(cs)), 0, 0)
+	t := pcapCint(ret)
+	if t < 0 {
+		return 0, statusError(pcapCint(t))
+	}
+	return TimestampSource(t), nil
+}
+
+func (p *InactiveHandle) pcapGeterr() error {
+	ret, _, _ := syscall.Syscall(pcapGeterrPtr, 1, uintptr(p.cptr), 0, 0)
+	return errors.New(bytePtrToString(ret))
+}
+
+func (p *InactiveHandle) pcapActivate() (*Handle, activateError) {
+	r, _, _ := syscall.Syscall(pcapActivatePtr, 1, uintptr(p.cptr), 0, 0)
+	ret := activateError(pcapCint(r))
+	if ret != aeNoError {
+		return nil, ret
+	}
+	h := &Handle{
+		cptr: p.cptr,
+	}
+	p.cptr = 0
+	return h, ret
+}
+
+func (p *InactiveHandle) pcapClose() {
+	if p.cptr != 0 {
+		_, _, _ = syscall.Syscall(pcapClosePtr, 1, uintptr(p.cptr), 0, 0)
+	}
+	p.cptr = 0
+}
+
+func pcapCreate(device string) (*InactiveHandle, error) {
+	err := LoadWinPCAP()
+	if err != nil {
+		return nil, err
+	}
+
+	buf := make([]byte, errorBufferSize)
+	dev, err := syscall.BytePtrFromString(device)
+	if err != nil {
+		return nil, err
+	}
+	cptr, _, _ := syscall.Syscall(pcapCreatePtr, 2, uintptr(unsafe.Pointer(dev)), uintptr(unsafe.Pointer(&buf[0])), 0)
+	if cptr == 0 {
+		return nil, errors.New(byteSliceToString(buf))
+	}
+	return &InactiveHandle{cptr: pcapTPtr(cptr)}, nil
+}
+
+func (p *InactiveHandle) pcapSetSnaplen(snaplen int) error {
+	status, _, _ := syscall.Syscall(pcapSetSnaplenPtr, 2, uintptr(p.cptr), uintptr(snaplen), 0)
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetPromisc(promisc bool) error {
+	var pro uintptr
+	if promisc {
+		pro = 1
+	}
+	status, _, _ := syscall.Syscall(pcapSetPromiscPtr, 2, uintptr(p.cptr), pro, 0)
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetTimeout(timeout time.Duration) error {
+	status, _, _ := syscall.Syscall(pcapSetTimeoutPtr, 2, uintptr(p.cptr), uintptr(timeoutMillis(timeout)), 0)
+
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapListTstampTypes() (out []TimestampSource) {
+	//libpcap <1.2 doesn't have pcap_*_tstamp_* functions
+	if pcapListTstampTypesPtr == 0 {
+		return
+	}
+	var types *pcapCint
+	ret, _, _ := syscall.Syscall(pcapListTstampTypesPtr, 2, uintptr(p.cptr), uintptr(unsafe.Pointer(&types)), 0)
+	n := int(pcapCint(ret))
+	if n < 0 {
+		return // public interface doesn't have error :(
+	}
+	defer syscall.Syscall(pcapFreeTstampTypesPtr, 1, uintptr(unsafe.Pointer(types)), 0, 0)
+	typesArray := (*[1 << 28]pcapCint)(unsafe.Pointer(types))
+	for i := 0; i < n; i++ {
+		out = append(out, TimestampSource((*typesArray)[i]))
+	}
+	return
+}
+
+func (p *InactiveHandle) pcapSetTstampType(t TimestampSource) error {
+	//libpcap <1.2 doesn't have pcap_*_tstamp_* functions
+	if pcapSetTstampTypePtr == 0 {
+		return statusError(pcapError)
+	}
+	status, _, _ := syscall.Syscall(pcapSetTstampTypePtr, 2, uintptr(p.cptr), uintptr(t), 0)
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetRfmon(monitor bool) error {
+	//winpcap does not support rfmon
+	if pcapCanSetRfmonPtr == 0 {
+		return CannotSetRFMon
+	}
+	var mon uintptr
+	if monitor {
+		mon = 1
+	}
+	canset, _, _ := syscall.Syscall(pcapCanSetRfmonPtr, 1, uintptr(p.cptr), 0, 0)
+	switch canset {
+	case 0:
+		return CannotSetRFMon
+	case 1:
+		// success
+	default:
+		return statusError(pcapCint(canset))
+	}
+	status, _, _ := syscall.Syscall(pcapSetRfmonPtr, 2, uintptr(p.cptr), mon, 0)
+	if status != 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetBufferSize(bufferSize int) error {
+	status, _, _ := syscall.Syscall(pcapSetBufferSizePtr, 2, uintptr(p.cptr), uintptr(bufferSize), 0)
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *InactiveHandle) pcapSetImmediateMode(mode bool) error {
+	//libpcap <1.5 does not have pcap_set_immediate_mode
+	if pcapSetImmediateModePtr == 0 {
+		return statusError(pcapError)
+	}
+	var md uintptr
+	if mode {
+		md = 1
+	}
+	status, _, _ := syscall.Syscall(pcapSetImmediateModePtr, 2, uintptr(p.cptr), md, 0)
+	if pcapCint(status) < 0 {
+		return statusError(pcapCint(status))
+	}
+	return nil
+}
+
+func (p *Handle) setNonBlocking() error {
+	// do nothing
+	return nil
+}
+
+// waitForPacket waits for a packet or for the timeout to expire.
+func (p *Handle) waitForPacket() {
+	// can't use select() so instead just switch goroutines
+	runtime.Gosched()
+}
+
+// openOfflineFile returns contents of input file as a *Handle.
+func openOfflineFile(file *os.File) (handle *Handle, err error) {
+	err = LoadWinPCAP()
+	if err != nil {
+		return nil, err
+	}
+
+	buf := make([]byte, errorBufferSize)
+	cf := file.Fd()
+
+	var cptr uintptr
+	if pcapOpenOfflineWithTstampPrecisionPtr == 0 {
+		cptr, _, _ = syscall.Syscall(pcapHopenOfflinePtr, 2, cf, uintptr(unsafe.Pointer(&buf[0])), 0)
+	} else {
+		cptr, _, _ = syscall.Syscall(pcapHOpenOfflineWithTstampPrecisionPtr, 3, cf, uintptr(pcapTstampPrecisionNano), uintptr(unsafe.Pointer(&buf[0])))
+	}
+
+	if cptr == 0 {
+		return nil, errors.New(byteSliceToString(buf))
+	}
+	return &Handle{cptr: pcapTPtr(cptr)}, nil
+}
diff --git a/vendor/github.com/google/gopacket/pcap/test_dns.pcap b/vendor/github.com/google/gopacket/pcap/test_dns.pcap
new file mode 100644
index 0000000..3a79f92
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/test_dns.pcap
Binary files differ
diff --git a/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap b/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap
new file mode 100644
index 0000000..1d01bd9
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap
Binary files differ
diff --git a/vendor/github.com/google/gopacket/pcap/test_loopback.pcap b/vendor/github.com/google/gopacket/pcap/test_loopback.pcap
new file mode 100644
index 0000000..ddeb82c
--- /dev/null
+++ b/vendor/github.com/google/gopacket/pcap/test_loopback.pcap
Binary files differ