1//+build linux
2
3package socket
4
5import (
6	"os"
7	"unsafe"
8
9	"golang.org/x/net/bpf"
10	"golang.org/x/sys/unix"
11)
12
13// SetBPF attaches an assembled BPF program to a Conn.
14func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
15	// We can't point to the first instruction in the array if no instructions
16	// are present.
17	if len(filter) == 0 {
18		return os.NewSyscallError("setsockopt", unix.EINVAL)
19	}
20
21	prog := unix.SockFprog{
22		Len:    uint16(len(filter)),
23		Filter: (*unix.SockFilter)(unsafe.Pointer(&filter[0])),
24	}
25
26	return c.SetsockoptSockFprog(unix.SOL_SOCKET, unix.SO_ATTACH_FILTER, &prog)
27}
28
29// RemoveBPF removes a BPF filter from a Conn.
30func (c *Conn) RemoveBPF() error {
31	// 0 argument is ignored.
32	return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_DETACH_FILTER, 0)
33}
34
35// SetsockoptSockFprog wraps setsockopt(2) for unix.SockFprog values.
36func (c *Conn) SetsockoptSockFprog(level, opt int, fprog *unix.SockFprog) error {
37	const op = "setsockopt"
38
39	var err error
40	doErr := c.control(op, func(fd int) error {
41		err = unix.SetsockoptSockFprog(fd, level, opt, fprog)
42		return err
43	})
44	if doErr != nil {
45		return doErr
46	}
47
48	return os.NewSyscallError(op, err)
49}
50