From ad8a32dbd3b774702edf46e5b0f774ebd6380082 Mon Sep 17 00:00:00 2001 From: Matthew Ellison Date: Mon, 22 May 2017 15:49:13 -0400 Subject: [PATCH] linux: Adds Persistent Devs + Setting Owner/Group --- params_linux.go | 16 +++++++++++- syscalls_linux.go | 63 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/params_linux.go b/params_linux.go index 9449f31..cff2f16 100644 --- a/params_linux.go +++ b/params_linux.go @@ -10,8 +10,22 @@ type PlatformSpecificParams struct { // field, i.e. an empty string, indicates that the default name should be // used. Name string + + // Enable or disable persistence mode for the interface device. + Persist bool + + // ID of the user which will be granted ownership of the device. + // The default value of -1 specifies that any user may use the device. + Owner int + + // ID of the group which will be granted access to the device. + // The default value of -1 specifies that any group may use the device. + Group int } func defaultPlatformSpecificParams() PlatformSpecificParams { - return PlatformSpecificParams{} + return PlatformSpecificParams{ + Owner: -1, + Group: -1, + } } diff --git a/syscalls_linux.go b/syscalls_linux.go index 420a645..a2e75f9 100644 --- a/syscalls_linux.go +++ b/syscalls_linux.go @@ -21,6 +21,14 @@ type ifReq struct { pad [0x28 - 0x10 - 2]byte } +func ioctl(fd uintptr, request int, argp uintptr) error { + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(request), argp) + if errno != 0 { + return os.NewSyscallError("ioctl", errno) + } + return nil +} + func newTAP(config Config) (ifce *Interface, err error) { file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) if err != nil { @@ -30,6 +38,26 @@ func newTAP(config Config) (ifce *Interface, err error) { if err != nil { return nil, err } + + // Set Device Owner + if config.Owner >= 0 { + if err = ioctl(file.Fd(), syscall.TUNSETOWNER, uintptr(config.Owner)); err != nil { + return + } + } + + // Set Device Group + if config.Group >= 0 { + if err = ioctl(file.Fd(), syscall.TUNSETGROUP, uintptr(config.Group)); err != nil { + return + } + } + + // Set/Clear Persist Device Flag + if err = setPersistence(file.Fd(), config.Persist); err != nil { + return + } + ifce = &Interface{isTAP: true, ReadWriteCloser: file, name: name} return } @@ -43,6 +71,26 @@ func newTUN(config Config) (ifce *Interface, err error) { if err != nil { return nil, err } + + // Set Device Owner + if config.Owner >= 0 { + if err = ioctl(file.Fd(), syscall.TUNSETOWNER, uintptr(config.Owner)); err != nil { + return + } + } + + // Set Device Group + if config.Group >= 0 { + if err = ioctl(file.Fd(), syscall.TUNSETGROUP, uintptr(config.Group)); err != nil { + return + } + } + + // Set/Clear Persist Device Flag + if err = setPersistence(file.Fd(), config.Persist); err != nil { + return + } + ifce = &Interface{isTAP: false, ReadWriteCloser: file, name: name} return } @@ -51,11 +99,20 @@ func createInterface(fd uintptr, ifName string, flags uint16) (createdIFName str 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 + + err = ioctl(fd, syscall.TUNSETIFF, uintptr(unsafe.Pointer(&req))) + if err != nil { return } + createdIFName = strings.Trim(string(req.Name[:]), "\x00") return } + +func setPersistence(fd uintptr, enabled bool) error { + value := 0; + if enabled { + value = 1 + } + return ioctl(fd, syscall.TUNSETPERSIST, uintptr(value)) +}