bpf_bsd.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build darwin dragonfly freebsd netbsd openbsd
  5. // Berkeley packet filter for BSD variants
  6. package unix
  7. import (
  8. "syscall"
  9. "unsafe"
  10. )
  11. func BpfStmt(code, k int) *BpfInsn {
  12. return &BpfInsn{Code: uint16(code), K: uint32(k)}
  13. }
  14. func BpfJump(code, k, jt, jf int) *BpfInsn {
  15. return &BpfInsn{Code: uint16(code), Jt: uint8(jt), Jf: uint8(jf), K: uint32(k)}
  16. }
  17. func BpfBuflen(fd int) (int, error) {
  18. var l int
  19. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGBLEN, uintptr(unsafe.Pointer(&l)))
  20. if err != 0 {
  21. return 0, syscall.Errno(err)
  22. }
  23. return l, nil
  24. }
  25. func SetBpfBuflen(fd, l int) (int, error) {
  26. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSBLEN, uintptr(unsafe.Pointer(&l)))
  27. if err != 0 {
  28. return 0, syscall.Errno(err)
  29. }
  30. return l, nil
  31. }
  32. func BpfDatalink(fd int) (int, error) {
  33. var t int
  34. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGDLT, uintptr(unsafe.Pointer(&t)))
  35. if err != 0 {
  36. return 0, syscall.Errno(err)
  37. }
  38. return t, nil
  39. }
  40. func SetBpfDatalink(fd, t int) (int, error) {
  41. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSDLT, uintptr(unsafe.Pointer(&t)))
  42. if err != 0 {
  43. return 0, syscall.Errno(err)
  44. }
  45. return t, nil
  46. }
  47. func SetBpfPromisc(fd, m int) error {
  48. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCPROMISC, uintptr(unsafe.Pointer(&m)))
  49. if err != 0 {
  50. return syscall.Errno(err)
  51. }
  52. return nil
  53. }
  54. func FlushBpf(fd int) error {
  55. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCFLUSH, 0)
  56. if err != 0 {
  57. return syscall.Errno(err)
  58. }
  59. return nil
  60. }
  61. type ivalue struct {
  62. name [IFNAMSIZ]byte
  63. value int16
  64. }
  65. func BpfInterface(fd int, name string) (string, error) {
  66. var iv ivalue
  67. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGETIF, uintptr(unsafe.Pointer(&iv)))
  68. if err != 0 {
  69. return "", syscall.Errno(err)
  70. }
  71. return name, nil
  72. }
  73. func SetBpfInterface(fd int, name string) error {
  74. var iv ivalue
  75. copy(iv.name[:], []byte(name))
  76. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETIF, uintptr(unsafe.Pointer(&iv)))
  77. if err != 0 {
  78. return syscall.Errno(err)
  79. }
  80. return nil
  81. }
  82. func BpfTimeout(fd int) (*Timeval, error) {
  83. var tv Timeval
  84. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGRTIMEOUT, uintptr(unsafe.Pointer(&tv)))
  85. if err != 0 {
  86. return nil, syscall.Errno(err)
  87. }
  88. return &tv, nil
  89. }
  90. func SetBpfTimeout(fd int, tv *Timeval) error {
  91. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSRTIMEOUT, uintptr(unsafe.Pointer(tv)))
  92. if err != 0 {
  93. return syscall.Errno(err)
  94. }
  95. return nil
  96. }
  97. func BpfStats(fd int) (*BpfStat, error) {
  98. var s BpfStat
  99. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGSTATS, uintptr(unsafe.Pointer(&s)))
  100. if err != 0 {
  101. return nil, syscall.Errno(err)
  102. }
  103. return &s, nil
  104. }
  105. func SetBpfImmediate(fd, m int) error {
  106. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCIMMEDIATE, uintptr(unsafe.Pointer(&m)))
  107. if err != 0 {
  108. return syscall.Errno(err)
  109. }
  110. return nil
  111. }
  112. func SetBpf(fd int, i []BpfInsn) error {
  113. var p BpfProgram
  114. p.Len = uint32(len(i))
  115. p.Insns = (*BpfInsn)(unsafe.Pointer(&i[0]))
  116. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETF, uintptr(unsafe.Pointer(&p)))
  117. if err != 0 {
  118. return syscall.Errno(err)
  119. }
  120. return nil
  121. }
  122. func CheckBpfVersion(fd int) error {
  123. var v BpfVersion
  124. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCVERSION, uintptr(unsafe.Pointer(&v)))
  125. if err != 0 {
  126. return syscall.Errno(err)
  127. }
  128. if v.Major != BPF_MAJOR_VERSION || v.Minor != BPF_MINOR_VERSION {
  129. return EINVAL
  130. }
  131. return nil
  132. }
  133. func BpfHeadercmpl(fd int) (int, error) {
  134. var f int
  135. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGHDRCMPLT, uintptr(unsafe.Pointer(&f)))
  136. if err != 0 {
  137. return 0, syscall.Errno(err)
  138. }
  139. return f, nil
  140. }
  141. func SetBpfHeadercmpl(fd, f int) error {
  142. _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSHDRCMPLT, uintptr(unsafe.Pointer(&f)))
  143. if err != 0 {
  144. return syscall.Errno(err)
  145. }
  146. return nil
  147. }