conn_linux.go 1.1 KB

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