Пример #1
0
func main() {
	enable := 1

	fd, err := syscall.Open("/dev/bpf0", syscall.O_RDWR, syscall.S_IRUSR|syscall.S_IWUSR)
	if err != nil {
		panic(err)
	}
	err = syscall.SetBpfInterface(fd, "vtnet0")
	if err != nil {
		panic(err)
	}
	err = syscall.SetBpfImmediate(fd, enable)
	if err != nil {
		panic(err)
	}
	err = syscall.SetBpfHeadercmpl(fd, enable)
	if err != nil {
		panic(err)
	}

	var bufLen int
	bufLen, err = syscall.BpfBuflen(fd)
	if err != nil {
		panic(err)
	}
	fmt.Printf("buflen %d\n", bufLen)

	err = syscall.SetBpfPromisc(fd, enable)
	if err != nil {
		panic(err)
	}

	var n int
	for {
		buf := make([]byte, bufLen)
		n, err = syscall.Read(fd, buf)
		if err != nil {
			panic(err)
		}
		//fmt.Printf("% X\n", buf[:n])
		fmt.Printf("\npacket of size %d captured\n", n)
		fmt.Print(hex.Dump(buf[:n]))

	}
}
Пример #2
0
// configureBPF configures a BPF device with the specified file descriptor to
// use the specified network and interface and protocol.
func configureBPF(fd int, ifi *net.Interface, proto Protocol) (int, error) {
	// Use specified interface with BPF device
	if err := syscall.SetBpfInterface(fd, ifi.Name); err != nil {
		return 0, err
	}

	// Inform BPF to send us its data immediately
	if err := syscall.SetBpfImmediate(fd, 1); err != nil {
		return 0, err
	}

	// Check buffer size of BPF device
	buflen, err := syscall.BpfBuflen(fd)
	if err != nil {
		return 0, err
	}

	// Do not automatically complete source address in ethernet headers
	if err := syscall.SetBpfHeadercmpl(fd, 0); err != nil {
		return 0, err
	}

	// Only retrieve incoming traffic using BPF device
	if err := setBPFDirection(fd, bpfDIn); err != nil {
		return 0, err
	}

	// Build and apply base BPF filter which checks for correct EtherType
	// on incoming packets
	prog, err := bpf.Assemble(baseInterfaceFilter(proto, ifi.MTU))
	if err != nil {
		return 0, err
	}
	if err := syscall.SetBpf(fd, assembleBpfInsn(prog)); err != nil {
		return 0, err
	}

	// Flush any packets currently in the BPF device's buffer
	if err := syscall.FlushBpf(fd); err != nil {
		return 0, err
	}

	return buflen, nil
}
Пример #3
0
func initialize(iface net.Interface) (err error) {
	verboseLog.Println("search available /dev/bpfX")
	for i := 0; i <= 10; i++ {
		bpfPath := fmt.Sprintf("/dev/bpf%d", i)
		bpf, err = os.OpenFile(bpfPath, os.O_RDWR, 0666)
		if err != nil {
			verboseLog.Printf("  open failed: %s - %s\n", bpfPath, err.Error())
		} else {
			verboseLog.Printf("  open success: %s\n", bpfPath)
			break
		}
	}
	bpfFd = int(bpf.Fd())
	if bpfFd == -1 {
		return errors.New("unable to open /dev/bpfX")
	}

	if err := syscall.SetBpfInterface(bpfFd, iface.Name); err != nil {
		return err
	}

	if err := syscall.SetBpfImmediate(bpfFd, 1); err != nil {
		return err
	}

	buflen, err = syscall.BpfBuflen(bpfFd)
	if err != nil {
		return err
	}

	if err := syscall.SetBpf(bpfFd, bpfArpFilter); err != nil {
		return err
	}

	if err := syscall.FlushBpf(bpfFd); err != nil {
		return err
	}

	return nil
}
Пример #4
0
func prepareBPF(fd int, name string) (int, error) {
	if err := syscall.SetBpfInterface(fd, name); err != nil {
		return 0, err
	}
	if err := syscall.CheckBpfVersion(fd); err != nil {
		return 0, err
	}
	if err := syscall.SetBpfImmediate(fd, 1); err != nil {
		return 0, err
	}
	if err := syscall.SetBpfPromisc(fd, 1); err != nil {
		return 0, err
	}
	buflen, err := syscall.BpfBuflen(fd)
	if err != nil {
		return 0, err
	}
	if _, err = syscall.BpfHeadercmpl(fd); err != nil {
		return 0, err
	}
	if err := syscall.SetBpfHeadercmpl(fd, 0); err != nil {
		return 0, err
	}
	if _, err := syscall.BpfTimeout(fd); err != nil {
		return 0, err
	}
	tv := syscall.Timeval{Usec: 10}
	if err := syscall.SetBpfTimeout(fd, &tv); err != nil {
		return 0, err
	}
	if err := syscall.SetBpf(fd, ipv6OverEthernet); err != nil {
		return 0, nil
	}
	if err := syscall.FlushBpf(fd); err != nil {
		return 0, err
	}
	return buflen, nil
}
Пример #5
0
// 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
}