示例#1
0
// SetBPF attaches an assembled BPF program to a raw net.PacketConn.
func (p *packetConn) SetBPF(filter []bpf.RawInstruction) error {
	// Base filter filters traffic based on EtherType
	base, err := bpf.Assemble(baseFilter(p.proto))
	if err != nil {
		return err
	}

	// Append user filter to base filter, translate to raw format,
	// and apply to BPF device
	return syscall.SetBpf(p.fd, assembleBpfInsn(append(base, filter...)))
}
示例#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
}