func openTun(ch chan int, timer *time.Timer) {
fd, err := unix.Open("/dev/net/tun", unix.O_RDWR|unix.O_NONBLOCK, 0)
if err != nil {
panic(err)
}
defer unix.Close(fd)
var ifr struct {
name [16]byte
flags uint16
_ [22]byte
}
ifr.flags = unix.IFF_TUN | unix.IFF_NO_PI
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), unix.TUNSETIFF, uintptr(unsafe.Pointer(&ifr)))
if errno != 0 {
log.Println("err to syscall:", errno)
return
}
ch <- fd
bytes := []byte("hell can you recv?")
fmt.Println(unix.Write(fd, bytes))
ticker := time.NewTicker(time.Second * 10)
for {
select {
case <-ticker.C:
fmt.Println(unix.Write(fd, bytes))
case <-timer.C:
return
}
}
}
func readFd(fd int) {
ticker := time.NewTicker(time.Second * 10)
buffer := make([]byte, 1024)
for {
<-ticker.C
n, err := unix.Read(fd, buffer)
if err != nil {
if err == unix.EAGAIN {
log.Println("No data available at the moment")
} else {
log.Println("Error reading from file descriptor:", err)
return
}
} else {
log.Println("reading from file descriptor:", string(buffer[:n]))
}
}
}
func main() {
fdchannel, done := make(chan int, 1), time.NewTimer(time.Minute)
go openTun(fdchannel, done)
fd := <-fdchannel
log.Println("opened fd", fd)
go readFd(fd)
<- done.C
}