Home | History | Annotate | Download | only in syscall
      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