Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 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 | |
Joel Sing | 8f3f4c9 | 2013-08-24 01:51:25 +1000 | [diff] [blame] | 5 | // +build darwin dragonfly freebsd netbsd openbsd |
Russ Cox | 2715956 | 2011-09-15 16:48:57 -0400 | [diff] [blame] | 6 | |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 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 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 23 | func BpfBuflen(fd int) (int, error) { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 24 | var l int |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 25 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGBLEN, uintptr(unsafe.Pointer(&l))) |
| 26 | if err != 0 { |
| 27 | return 0, Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 28 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 29 | return l, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 30 | } |
| 31 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 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) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 36 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 37 | return l, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 38 | } |
| 39 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 40 | func BpfDatalink(fd int) (int, error) { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 41 | var t int |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 42 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGDLT, uintptr(unsafe.Pointer(&t))) |
| 43 | if err != 0 { |
| 44 | return 0, Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 45 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 46 | return t, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 47 | } |
| 48 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 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) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 53 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 54 | return t, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 55 | } |
| 56 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 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) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 61 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 62 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 63 | } |
| 64 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 65 | func FlushBpf(fd int) error { |
| 66 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCFLUSH, 0) |
| 67 | if err != 0 { |
| 68 | return Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 69 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 70 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | type ivalue struct { |
| 74 | name [IFNAMSIZ]byte |
| 75 | value int16 |
| 76 | } |
| 77 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 78 | func BpfInterface(fd int, name string) (string, error) { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 79 | var iv ivalue |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 80 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGETIF, uintptr(unsafe.Pointer(&iv))) |
| 81 | if err != 0 { |
| 82 | return "", Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 83 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 84 | return name, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 85 | } |
| 86 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 87 | func SetBpfInterface(fd int, name string) error { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 88 | var iv ivalue |
| 89 | copy(iv.name[:], []byte(name)) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 90 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETIF, uintptr(unsafe.Pointer(&iv))) |
| 91 | if err != 0 { |
| 92 | return Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 93 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 94 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 95 | } |
| 96 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 97 | func BpfTimeout(fd int) (*Timeval, error) { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 98 | var tv Timeval |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 99 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGRTIMEOUT, uintptr(unsafe.Pointer(&tv))) |
| 100 | if err != 0 { |
| 101 | return nil, Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 102 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 103 | return &tv, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 104 | } |
| 105 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 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) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 110 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 111 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 112 | } |
| 113 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 114 | func BpfStats(fd int) (*BpfStat, error) { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 115 | var s BpfStat |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 116 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGSTATS, uintptr(unsafe.Pointer(&s))) |
| 117 | if err != 0 { |
| 118 | return nil, Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 119 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 120 | return &s, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 121 | } |
| 122 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 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) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 127 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 128 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 129 | } |
| 130 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 131 | func SetBpf(fd int, i []BpfInsn) error { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 132 | var p BpfProgram |
| 133 | p.Len = uint32(len(i)) |
| 134 | p.Insns = (*BpfInsn)(unsafe.Pointer(&i[0])) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 135 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETF, uintptr(unsafe.Pointer(&p))) |
| 136 | if err != 0 { |
| 137 | return Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 138 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 139 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 140 | } |
| 141 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 142 | func CheckBpfVersion(fd int) error { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 143 | var v BpfVersion |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 144 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCVERSION, uintptr(unsafe.Pointer(&v))) |
| 145 | if err != 0 { |
| 146 | return Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 147 | } |
| 148 | if v.Major != BPF_MAJOR_VERSION || v.Minor != BPF_MINOR_VERSION { |
| 149 | return EINVAL |
| 150 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 151 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 152 | } |
| 153 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 154 | func BpfHeadercmpl(fd int) (int, error) { |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 155 | var f int |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 156 | _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGHDRCMPLT, uintptr(unsafe.Pointer(&f))) |
| 157 | if err != 0 { |
| 158 | return 0, Errno(err) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 159 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 160 | return f, nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 161 | } |
| 162 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 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) |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 167 | } |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 168 | return nil |
Mikio Hara | b100a29 | 2011-06-14 11:28:36 -0400 | [diff] [blame] | 169 | } |