aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go')
-rw-r--r--vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go215
1 files changed, 0 insertions, 215 deletions
diff --git a/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go b/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go
deleted file mode 100644
index 3e1da0b..0000000
--- a/vendor/github.com/google/gopacket/bsdbpf/bsd_bpf_sniffer.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// 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.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-package bsdbpf
-
-import (
- "errors"
- "fmt"
- "syscall"
- "time"
- "unsafe"
-
- "github.com/google/gopacket"
- "golang.org/x/sys/unix"
-)
-
-const wordSize = int(unsafe.Sizeof(uintptr(0)))
-
-func bpfWordAlign(x int) int {
- return (((x) + (wordSize - 1)) &^ (wordSize - 1))
-}
-
-// Options is used to configure various properties of the BPF sniffer.
-// Default values are used when a nil Options pointer is passed to NewBPFSniffer.
-type Options struct {
- // BPFDeviceName is name of the bpf device to use for sniffing
- // the network device. The default value of BPFDeviceName is empty string
- // which causes the first available BPF device file /dev/bpfX to be used.
- BPFDeviceName string
- // ReadBufLen specifies the size of the buffer used to read packets
- // off the wire such that multiple packets are buffered with each read syscall.
- // Note that an individual packet larger than the buffer size is necessarily truncated.
- // A larger buffer should increase performance because fewer read syscalls would be made.
- // If zero is used, the system's default buffer length will be used which depending on the
- // system may default to 4096 bytes which is not big enough to accomodate some link layers
- // such as WLAN (802.11).
- // ReadBufLen defaults to 32767... however typical BSD manual pages for BPF indicate that
- // if the requested buffer size cannot be accommodated, the closest allowable size will be
- // set and returned... hence our GetReadBufLen method.
- ReadBufLen int
- // Timeout is the length of time to wait before timing out on a read request.
- // Timeout defaults to nil which means no timeout is used.
- Timeout *syscall.Timeval
- // Promisc is set to true for promiscuous mode ethernet sniffing.
- // Promisc defaults to true.
- Promisc bool
- // Immediate is set to true to make our read requests return as soon as a packet becomes available.
- // Otherwise, a read will block until either the kernel buffer becomes full or a timeout occurs.
- // The default is true.
- Immediate bool
- // PreserveLinkAddr is set to false if the link level source address should be filled in automatically
- // by the interface output routine. Set to true if the link level source address will be written,
- // as provided, to the wire.
- // The default is true.
- PreserveLinkAddr bool
-}
-
-var defaultOptions = Options{
- BPFDeviceName: "",
- ReadBufLen: 32767,
- Timeout: nil,
- Promisc: true,
- Immediate: true,
- PreserveLinkAddr: true,
-}
-
-// BPFSniffer is a struct used to track state of a BSD BPF ethernet sniffer
-// such that gopacket's PacketDataSource interface is implemented.
-type BPFSniffer struct {
- options *Options
- sniffDeviceName string
- fd int
- readBuffer []byte
- lastReadLen int
- readBytesConsumed int
-}
-
-// NewBPFSniffer is used to create BSD-only BPF ethernet sniffer
-// iface is the network interface device name that you wish to sniff
-// options can set to nil in order to utilize default values for everything.
-// Each field of Options also have a default setting if left unspecified by
-// the user's custome Options struct.
-func NewBPFSniffer(iface string, options *Options) (*BPFSniffer, error) {
- var err error
- enable := 1
- sniffer := BPFSniffer{
- sniffDeviceName: iface,
- }
- if options == nil {
- sniffer.options = &defaultOptions
- } else {
- sniffer.options = options
- }
-
- if sniffer.options.BPFDeviceName == "" {
- sniffer.pickBpfDevice()
- }
-
- // setup our read buffer
- if sniffer.options.ReadBufLen == 0 {
- sniffer.options.ReadBufLen, err = syscall.BpfBuflen(sniffer.fd)
- if err != nil {
- return nil, err
- }
- } else {
- sniffer.options.ReadBufLen, err = syscall.SetBpfBuflen(sniffer.fd, sniffer.options.ReadBufLen)
- if err != nil {
- return nil, err
- }
- }
- sniffer.readBuffer = make([]byte, sniffer.options.ReadBufLen)
-
- err = syscall.SetBpfInterface(sniffer.fd, sniffer.sniffDeviceName)
- if err != nil {
- return nil, err
- }
-
- if sniffer.options.Immediate {
- // turn immediate mode on. This makes the snffer non-blocking.
- err = syscall.SetBpfImmediate(sniffer.fd, enable)
- if err != nil {
- return nil, err
- }
- }
-
- // the above call to syscall.SetBpfImmediate needs to be made
- // before setting a timer otherwise the reads will block for the
- // entire timer duration even if there are packets to return.
- if sniffer.options.Timeout != nil {
- err = syscall.SetBpfTimeout(sniffer.fd, sniffer.options.Timeout)
- if err != nil {
- return nil, err
- }
- }
-
- if sniffer.options.PreserveLinkAddr {
- // preserves the link level source address...
- // higher level protocol analyzers will not need this
- err = syscall.SetBpfHeadercmpl(sniffer.fd, enable)
- if err != nil {
- return nil, err
- }
- }
-
- if sniffer.options.Promisc {
- // forces the interface into promiscuous mode
- err = syscall.SetBpfPromisc(sniffer.fd, enable)
- if err != nil {
- return nil, err
- }
- }
-
- return &sniffer, nil
-}
-
-// Close is used to close the file-descriptor of the BPF device file.
-func (b *BPFSniffer) Close() error {
- return syscall.Close(b.fd)
-}
-
-func (b *BPFSniffer) pickBpfDevice() {
- var err error
- b.options.BPFDeviceName = ""
- for i := 0; i < 99; i++ {
- b.options.BPFDeviceName = fmt.Sprintf("/dev/bpf%d", i)
- b.fd, err = syscall.Open(b.options.BPFDeviceName, syscall.O_RDWR, 0)
- if err == nil {
- return
- }
- }
- panic("failed to acquire a BPF device for read-write access")
-}
-
-func (b *BPFSniffer) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) {
- var err error
- if b.readBytesConsumed >= b.lastReadLen {
- b.readBytesConsumed = 0
- b.readBuffer = make([]byte, b.options.ReadBufLen)
- b.lastReadLen, err = syscall.Read(b.fd, b.readBuffer)
- if err != nil {
- b.lastReadLen = 0
- return nil, gopacket.CaptureInfo{}, err
- }
- }
- hdr := (*unix.BpfHdr)(unsafe.Pointer(&b.readBuffer[b.readBytesConsumed]))
- frameStart := b.readBytesConsumed + int(hdr.Hdrlen)
- b.readBytesConsumed += bpfWordAlign(int(hdr.Hdrlen) + int(hdr.Caplen))
-
- if frameStart+int(hdr.Caplen) > len(b.readBuffer) {
- captureInfo := gopacket.CaptureInfo{
- Timestamp: time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000),
- CaptureLength: 0,
- Length: 0,
- }
- return nil, captureInfo, errors.New("BPF captured frame received with corrupted BpfHdr struct.")
- }
-
- rawFrame := b.readBuffer[frameStart : frameStart+int(hdr.Caplen)]
- captureInfo := gopacket.CaptureInfo{
- Timestamp: time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000),
- CaptureLength: len(rawFrame),
- Length: len(rawFrame),
- }
- return rawFrame, captureInfo, nil
-}
-
-// GetReadBufLen returns the BPF read buffer length
-func (b *BPFSniffer) GetReadBufLen() int {
- return b.options.ReadBufLen
-}