golang 实现tun虚拟网卡创建,启动,读,关闭
时间: 2024-06-05 07:06:26 浏览: 154
golang-chat:golang聊天服务器
package main
import (
"errors"
"log"
"net"
"os"
"os/exec"
"syscall"
"unsafe"
)
const (
tunDev = "/dev/net/tun"
ifreqLen = 40
)
type ifreq struct {
Name [16]byte
Flags uint16
pad [ifreqLen - 18]byte
}
func openTunDevice() (*os.File, error) {
f, err := os.OpenFile(tunDev, os.O_RDWR, 0)
if err != nil {
return nil, err
}
return f, nil
}
func createTunDevice(name string, addr net.IP, mask net.IPMask) (*os.File, error) {
f, err := openTunDevice()
if err != nil {
return nil, err
}
ifr := &ifreq{}
copy(ifr.Name[:], name)
ifr.Flags = syscall.IFF_TUN | syscall.IFF_NO_PI
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), syscall.TUNSETIFF, uintptr(unsafe.Pointer(ifr)))
if errno != 0 {
f.Close()
return nil, errors.New("failed to create tun device")
}
cmd := exec.Command("ip", "link", "set", "dev", name, "up")
if err := cmd.Run(); err != nil {
f.Close()
return nil, err
}
cmd = exec.Command("ip", "addr", "add", addr.String()+"/"+mask.String(), "dev", name)
if err := cmd.Run(); err != nil {
f.Close()
return nil, err
}
return f, nil
}
func readTunDevice(f *os.File, buf []byte) (int, error) {
n, err := f.Read(buf)
if err != nil {
return 0, err
}
return n, nil
}
func closeTunDevice(f *os.File) error {
return f.Close()
}
func main() {
name := "mytun"
addr := net.ParseIP("192.168.1.1")
mask := net.CIDRMask(24, 32)
f, err := createTunDevice(name, addr, mask)
if err != nil {
log.Fatal(err)
}
defer closeTunDevice(f)
buf := make([]byte, 1500)
for {
n, err := readTunDevice(f, buf)
if err != nil {
log.Println(err)
continue
}
log.Printf("read %d bytes from tun device: %v\n", n, buf[:n])
}
}
阅读全文