// 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)
}
