conn_linux.go 2.0 KB

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