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