blob: cc6c1e77c502c7e1c9e5da14f6fbe70ef4c4a7f6 [file] [log] [blame]
Mikio Harab100a292011-06-14 11:28:36 -04001// 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
Joel Sing8f3f4c92013-08-24 01:51:25 +10005// +build darwin dragonfly freebsd netbsd openbsd
Russ Cox27159562011-09-15 16:48:57 -04006
Mikio Harab100a292011-06-14 11:28:36 -04007// Berkeley packet filter for BSD variants
8
9package syscall
10
11import (
12 "unsafe"
13)
14
15func BpfStmt(code, k int) *BpfInsn {
16 return &BpfInsn{Code: uint16(code), K: uint32(k)}
17}
18
19func BpfJump(code, k, jt, jf int) *BpfInsn {
20 return &BpfInsn{Code: uint16(code), Jt: uint8(jt), Jf: uint8(jf), K: uint32(k)}
21}
22
Russ Coxc017a822011-11-13 22:44:52 -050023func BpfBuflen(fd int) (int, error) {
Mikio Harab100a292011-06-14 11:28:36 -040024 var l int
Russ Coxc017a822011-11-13 22:44:52 -050025 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGBLEN, uintptr(unsafe.Pointer(&l)))
26 if err != 0 {
27 return 0, Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -040028 }
Russ Coxc017a822011-11-13 22:44:52 -050029 return l, nil
Mikio Harab100a292011-06-14 11:28:36 -040030}
31
Russ Coxc017a822011-11-13 22:44:52 -050032func 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)
Mikio Harab100a292011-06-14 11:28:36 -040036 }
Russ Coxc017a822011-11-13 22:44:52 -050037 return l, nil
Mikio Harab100a292011-06-14 11:28:36 -040038}
39
Russ Coxc017a822011-11-13 22:44:52 -050040func BpfDatalink(fd int) (int, error) {
Mikio Harab100a292011-06-14 11:28:36 -040041 var t int
Russ Coxc017a822011-11-13 22:44:52 -050042 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGDLT, uintptr(unsafe.Pointer(&t)))
43 if err != 0 {
44 return 0, Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -040045 }
Russ Coxc017a822011-11-13 22:44:52 -050046 return t, nil
Mikio Harab100a292011-06-14 11:28:36 -040047}
48
Russ Coxc017a822011-11-13 22:44:52 -050049func 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)
Mikio Harab100a292011-06-14 11:28:36 -040053 }
Russ Coxc017a822011-11-13 22:44:52 -050054 return t, nil
Mikio Harab100a292011-06-14 11:28:36 -040055}
56
Russ Coxc017a822011-11-13 22:44:52 -050057func 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)
Mikio Harab100a292011-06-14 11:28:36 -040061 }
Russ Coxc017a822011-11-13 22:44:52 -050062 return nil
Mikio Harab100a292011-06-14 11:28:36 -040063}
64
Russ Coxc017a822011-11-13 22:44:52 -050065func FlushBpf(fd int) error {
66 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCFLUSH, 0)
67 if err != 0 {
68 return Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -040069 }
Russ Coxc017a822011-11-13 22:44:52 -050070 return nil
Mikio Harab100a292011-06-14 11:28:36 -040071}
72
73type ivalue struct {
74 name [IFNAMSIZ]byte
75 value int16
76}
77
Russ Coxc017a822011-11-13 22:44:52 -050078func BpfInterface(fd int, name string) (string, error) {
Mikio Harab100a292011-06-14 11:28:36 -040079 var iv ivalue
Russ Coxc017a822011-11-13 22:44:52 -050080 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGETIF, uintptr(unsafe.Pointer(&iv)))
81 if err != 0 {
82 return "", Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -040083 }
Russ Coxc017a822011-11-13 22:44:52 -050084 return name, nil
Mikio Harab100a292011-06-14 11:28:36 -040085}
86
Russ Coxc017a822011-11-13 22:44:52 -050087func SetBpfInterface(fd int, name string) error {
Mikio Harab100a292011-06-14 11:28:36 -040088 var iv ivalue
89 copy(iv.name[:], []byte(name))
Russ Coxc017a822011-11-13 22:44:52 -050090 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETIF, uintptr(unsafe.Pointer(&iv)))
91 if err != 0 {
92 return Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -040093 }
Russ Coxc017a822011-11-13 22:44:52 -050094 return nil
Mikio Harab100a292011-06-14 11:28:36 -040095}
96
Russ Coxc017a822011-11-13 22:44:52 -050097func BpfTimeout(fd int) (*Timeval, error) {
Mikio Harab100a292011-06-14 11:28:36 -040098 var tv Timeval
Russ Coxc017a822011-11-13 22:44:52 -050099 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGRTIMEOUT, uintptr(unsafe.Pointer(&tv)))
100 if err != 0 {
101 return nil, Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -0400102 }
Russ Coxc017a822011-11-13 22:44:52 -0500103 return &tv, nil
Mikio Harab100a292011-06-14 11:28:36 -0400104}
105
Russ Coxc017a822011-11-13 22:44:52 -0500106func 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)
Mikio Harab100a292011-06-14 11:28:36 -0400110 }
Russ Coxc017a822011-11-13 22:44:52 -0500111 return nil
Mikio Harab100a292011-06-14 11:28:36 -0400112}
113
Russ Coxc017a822011-11-13 22:44:52 -0500114func BpfStats(fd int) (*BpfStat, error) {
Mikio Harab100a292011-06-14 11:28:36 -0400115 var s BpfStat
Russ Coxc017a822011-11-13 22:44:52 -0500116 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGSTATS, uintptr(unsafe.Pointer(&s)))
117 if err != 0 {
118 return nil, Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -0400119 }
Russ Coxc017a822011-11-13 22:44:52 -0500120 return &s, nil
Mikio Harab100a292011-06-14 11:28:36 -0400121}
122
Russ Coxc017a822011-11-13 22:44:52 -0500123func 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)
Mikio Harab100a292011-06-14 11:28:36 -0400127 }
Russ Coxc017a822011-11-13 22:44:52 -0500128 return nil
Mikio Harab100a292011-06-14 11:28:36 -0400129}
130
Russ Coxc017a822011-11-13 22:44:52 -0500131func SetBpf(fd int, i []BpfInsn) error {
Mikio Harab100a292011-06-14 11:28:36 -0400132 var p BpfProgram
133 p.Len = uint32(len(i))
134 p.Insns = (*BpfInsn)(unsafe.Pointer(&i[0]))
Russ Coxc017a822011-11-13 22:44:52 -0500135 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETF, uintptr(unsafe.Pointer(&p)))
136 if err != 0 {
137 return Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -0400138 }
Russ Coxc017a822011-11-13 22:44:52 -0500139 return nil
Mikio Harab100a292011-06-14 11:28:36 -0400140}
141
Russ Coxc017a822011-11-13 22:44:52 -0500142func CheckBpfVersion(fd int) error {
Mikio Harab100a292011-06-14 11:28:36 -0400143 var v BpfVersion
Russ Coxc017a822011-11-13 22:44:52 -0500144 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCVERSION, uintptr(unsafe.Pointer(&v)))
145 if err != 0 {
146 return Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -0400147 }
148 if v.Major != BPF_MAJOR_VERSION || v.Minor != BPF_MINOR_VERSION {
149 return EINVAL
150 }
Russ Coxc017a822011-11-13 22:44:52 -0500151 return nil
Mikio Harab100a292011-06-14 11:28:36 -0400152}
153
Russ Coxc017a822011-11-13 22:44:52 -0500154func BpfHeadercmpl(fd int) (int, error) {
Mikio Harab100a292011-06-14 11:28:36 -0400155 var f int
Russ Coxc017a822011-11-13 22:44:52 -0500156 _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGHDRCMPLT, uintptr(unsafe.Pointer(&f)))
157 if err != 0 {
158 return 0, Errno(err)
Mikio Harab100a292011-06-14 11:28:36 -0400159 }
Russ Coxc017a822011-11-13 22:44:52 -0500160 return f, nil
Mikio Harab100a292011-06-14 11:28:36 -0400161}
162
Russ Coxc017a822011-11-13 22:44:52 -0500163func 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)
Mikio Harab100a292011-06-14 11:28:36 -0400167 }
Russ Coxc017a822011-11-13 22:44:52 -0500168 return nil
Mikio Harab100a292011-06-14 11:28:36 -0400169}