Committing vendored dependencies and generated protos

Change-Id: I349c149b513d9de7d9f60bde2c954a939da2fc54
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
+}