water/syscalls_linux.go
Matthew Ellison 70591d2499
Simplifies Platform Specific Interface Creation
The interface `Config` object is now passed directly into each creation
function in order to more easily use additional options.

In addition, the linux and darwin parameters were split to better
capture different options for each platform.
2017-05-23 09:06:42 -04:00

61 lines
1.3 KiB
Go

// +build linux
package water
import (
"os"
"strings"
"syscall"
"unsafe"
)
const (
cIFF_TUN = 0x0001
cIFF_TAP = 0x0002
cIFF_NO_PI = 0x1000
)
type ifReq struct {
Name [0x10]byte
Flags uint16
pad [0x28 - 0x10 - 2]byte
}
func newTAP(config Config) (ifce *Interface, err error) {
file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
if err != nil {
return nil, err
}
name, err := createInterface(file.Fd(), config.Name, cIFF_TAP|cIFF_NO_PI)
if err != nil {
return nil, err
}
ifce = &Interface{isTAP: true, ReadWriteCloser: file, name: name}
return
}
func newTUN(config Config) (ifce *Interface, err error) {
file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
if err != nil {
return nil, err
}
name, err := createInterface(file.Fd(), config.Name, cIFF_TUN|cIFF_NO_PI)
if err != nil {
return nil, err
}
ifce = &Interface{isTAP: false, ReadWriteCloser: file, name: name}
return
}
func createInterface(fd uintptr, ifName string, flags uint16) (createdIFName string, err error) {
var req ifReq
req.Flags = flags
copy(req.Name[:], ifName)
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&req)))
if errno != 0 {
err = errno
return
}
createdIFName = strings.Trim(string(req.Name[:]), "\x00")
return
}