Set interface flags properly on OpenBSD

This commit is contained in:
Neil Alexander 2018-03-01 15:02:53 +00:00
parent 9e4d169208
commit 90393ae03b
2 changed files with 45 additions and 18 deletions

View File

@ -2,6 +2,7 @@ package yggdrasil
// This manages the tun driver to send/recv packets to/from applications
import "os"
import ethernet "github.com/songgao/packets/ethernet"
const IPv6_HEADER_LENGTH = 40
@ -14,6 +15,7 @@ type tunInterface interface {
Read(to []byte) (int, error)
Write(from []byte) (int, error)
Close() error
FD() *os.File
}
type tunDevice struct {

View File

@ -2,16 +2,18 @@
package yggdrasil
import "fmt"
import "os/exec"
import "strings"
import "unsafe"
import "syscall"
import "golang.org/x/sys/unix"
import water "github.com/neilalexander/water"
// This is to catch BSD platforms
const TUNSIFINFO = (0x80000000) | ((4 & 0x1fff) << 16) | uint32(byte('t'))<<8 | 91
const TUNGIFINFO = (0x40000000) | ((4 & 0x1fff) << 16) | uint32(byte('t'))<<8 | 92
const TUNSIFINFO = (0x80000000) | ((12 & 0x1fff) << 16) | uint32(byte('t'))<<8 | 91
const TUNGIFINFO = (0x40000000) | ((12 & 0x1fff) << 16) | uint32(byte('t'))<<8 | 92
const SIOCAIFADDR_IN6 = (0x80000000) | ((4 & 0x1fff) << 16) | uint32(byte('i'))<<8 | 27
type in6_addrlifetime struct {
@ -40,10 +42,10 @@ type in6_aliasreq struct {
}
type tuninfo struct {
tun_baudrate int
tun_mtu int16
tun_type uint8
tun_dummy uint8
tun_mtu uint16
tun_type uint32
tun_flags uint32
tun_dummy uint16
}
func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error {
@ -67,23 +69,46 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int)
}
func (tun *tunDevice) setupAddress(addr string) error {
fd := tun.iface.FD().Fd()
var err error
var ti tuninfo
// Get the existing interface flags
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(TUNGIFINFO), uintptr(unsafe.Pointer(&ti))); errno != 0 {
err = errno
tun.core.log.Printf("Error in TUNGIFINFO: %v", errno)
return err
}
tun.core.log.Printf("TUNGIFINFO: %+v", ti)
// Set the new MTU
ti.tun_mtu = uint16(tun.mtu)
// Set the new interface flags
ti.tun_flags |= syscall.IFF_UP
switch {
case tun.iface.IsTAP():
ti.tun_flags |= syscall.IFF_MULTICAST
ti.tun_flags |= syscall.IFF_BROADCAST
case tun.iface.IsTUN():
ti.tun_flags |= syscall.IFF_POINTOPOINT
}
// Set the new interface flags
tun.core.log.Printf("TUNSIFINFO: %+v", ti)
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(TUNSIFINFO), uintptr(unsafe.Pointer(&ti))); errno != 0 {
err = errno
tun.core.log.Printf("Error in TUNSIFINFO: %v", errno)
return err
}
// Set address
cmd := exec.Command("ifconfig", tun.iface.Name(), "inet6", addr)
tun.core.log.Printf("ifconfig command: %v", strings.Join(cmd.Args, " "))
output, err := cmd.CombinedOutput()
if err != nil {
tun.core.log.Printf("ipconfig failed: %v.", err)
tun.core.log.Printf("ifconfig failed: %v.", err)
tun.core.log.Println(string(output))
return err
}
// Set MTU and bring device up
cmd = exec.Command("ifconfig", tun.iface.Name(), "mtu", fmt.Sprintf("%d", tun.mtu), "up")
tun.core.log.Printf("ifconfig command: %v", strings.Join(cmd.Args, " "))
output, err = cmd.CombinedOutput()
if err != nil {
tun.core.log.Printf("ipconfig failed: %v.", err)
tun.core.log.Println(string(output))
return err
}
return nil