فهرست منبع

linux: Adds Persistent Devs + Setting Owner/Group

Matthew Ellison 8 سال پیش
والد
کامیت
ad8a32dbd3
2فایلهای تغییر یافته به همراه75 افزوده شده و 4 حذف شده
  1. 15 1
      params_linux.go
  2. 60 3
      syscalls_linux.go

+ 15 - 1
params_linux.go

@@ -10,8 +10,22 @@ type PlatformSpecificParams struct {
 	// field, i.e. an empty string, indicates that the default name should be
 	// field, i.e. an empty string, indicates that the default name should be
 	// used.
 	// used.
 	Name string
 	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 {
 func defaultPlatformSpecificParams() PlatformSpecificParams {
-	return PlatformSpecificParams{}
+	return PlatformSpecificParams{
+		Owner: -1,
+		Group: -1,
+	}
 }
 }

+ 60 - 3
syscalls_linux.go

@@ -21,6 +21,14 @@ type ifReq struct {
 	pad   [0x28 - 0x10 - 2]byte
 	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) {
 func newTAP(config Config) (ifce *Interface, err error) {
 	file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
 	file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
 	if err != nil {
 	if err != nil {
@@ -30,6 +38,26 @@ func newTAP(config Config) (ifce *Interface, err error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		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}
 	ifce = &Interface{isTAP: true, ReadWriteCloser: file, name: name}
 	return
 	return
 }
 }
@@ -43,6 +71,26 @@ func newTUN(config Config) (ifce *Interface, err error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		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}
 	ifce = &Interface{isTAP: false, ReadWriteCloser: file, name: name}
 	return
 	return
 }
 }
@@ -51,11 +99,20 @@ func createInterface(fd uintptr, ifName string, flags uint16) (createdIFName str
 	var req ifReq
 	var req ifReq
 	req.Flags = flags
 	req.Flags = flags
 	copy(req.Name[:], ifName)
 	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
 		return
 	}
 	}
+
 	createdIFName = strings.Trim(string(req.Name[:]), "\x00")
 	createdIFName = strings.Trim(string(req.Name[:]), "\x00")
 	return
 	return
 }
 }
+
+func setPersistence(fd uintptr, enabled bool) error {
+	value := 0;
+	if enabled {
+		value = 1
+	}
+	return ioctl(fd, syscall.TUNSETPERSIST, uintptr(value))
+}