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
+}
