mirror of
https://github.com/yggdrasil-network/water.git
synced 2025-05-19 16:35:10 +03:00

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.
61 lines
1.3 KiB
Go
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
|
|
}
|