|
@@ -4,7 +4,9 @@ import (
|
|
"errors"
|
|
"errors"
|
|
"fmt"
|
|
"fmt"
|
|
"io"
|
|
"io"
|
|
|
|
+ "math"
|
|
"os"
|
|
"os"
|
|
|
|
+ "strconv"
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
"syscall"
|
|
"syscall"
|
|
@@ -75,6 +77,19 @@ func openDevSystem(config Config) (ifce *Interface, err error) {
|
|
if config.DeviceType != TUN {
|
|
if config.DeviceType != TUN {
|
|
return nil, errors.New("only tun is implemented for SystemDriver, use TunTapOSXDriver for tap")
|
|
return nil, errors.New("only tun is implemented for SystemDriver, use TunTapOSXDriver for tap")
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ ifIndex := -1
|
|
|
|
+ if config.Name != "" {
|
|
|
|
+ const utunPrefix = "utun"
|
|
|
|
+ if !strings.HasPrefix(config.Name, utunPrefix) {
|
|
|
|
+ return nil, fmt.Errorf("Interface name must be utun[0-9]+")
|
|
|
|
+ }
|
|
|
|
+ ifIndex, err = strconv.Atoi(config.Name[len(utunPrefix):])
|
|
|
|
+ if err != nil || ifIndex < 0 || ifIndex > math.MaxUint32-1 {
|
|
|
|
+ return nil, fmt.Errorf("Interface name must be utun[0-9]+")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
var fd int
|
|
var fd int
|
|
// Supposed to be socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), but ...
|
|
// Supposed to be socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), but ...
|
|
//
|
|
//
|
|
@@ -106,7 +121,7 @@ func openDevSystem(config Config) (ifce *Interface, err error) {
|
|
ssSysaddr: 2,
|
|
ssSysaddr: 2,
|
|
|
|
|
|
scID: ctlInfo.ctlID,
|
|
scID: ctlInfo.ctlID,
|
|
- scUnit: 0,
|
|
|
|
|
|
+ scUnit: uint32(ifIndex) + 1,
|
|
})
|
|
})
|
|
if _, _, errno := syscall.RawSyscall(syscall.SYS_CONNECT, uintptr(fd), uintptr(addrP), uintptr(sockaddrCtlSize)); errno != 0 {
|
|
if _, _, errno := syscall.RawSyscall(syscall.SYS_CONNECT, uintptr(fd), uintptr(addrP), uintptr(sockaddrCtlSize)); errno != 0 {
|
|
err = errno
|
|
err = errno
|