Tun虚拟网卡示例用法
\`\`\`go /\* \* @Author: dean 1028968939@qq.com \* @Date: 2024-07-13 12:05:39 \* @LastEditors: dean 1028968939@qq.com \* @LastEditTime: 2024-07-13 13:01:16 \* @FilePath: \\Workspace\\GoWorkSpace\\Demo\\main.go \* @Description: tun虚拟机网卡demo \*/ package main import ( "bufio" "fmt" "os" "os/exec" "syscall" "unsafe" ) // 定义 ifreq 结构体 type Ifreq struct { Name \[syscall.IFNAMSIZ\]byte // 接口名称 Flags uintptr // 标志位 } func createTunDevice(tunName string) (\*os.File, error) { // 打开 /dev/net/tun 设备 fd, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) if err != nil { return nil, err } // 准备 ifreq 结构体 var ifr Ifreq copy(ifr.Name\[:\], \[\]byte(tunName)) ifr.Flags = syscall.IFF_TUN \| syscall.IFF_NO_PI // 创建一个 Tun 设备 // 使用 ioctl 设置 Tun 设备 if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd.Fd()), syscall.TUNSETIFF, uintptr(unsafe.Pointer(\&ifr))); errno != 0 { fd.Close() return nil, fmt.Errorf("ioctl TUNSETIFF failed: %w", errno) } return fd, nil } func execCommand(command string) { cmd := exec.Command("/usr/bin/bash", "-c", command) _, err := cmd.CombinedOutput() if err != nil { fmt.Printf("命令执行失败: %s, %s\\n", command, err) return } } func main() { tunDeviceName := "tun0" // execCommand(fmt.Sprintf("ip tuntap del dev %s mode tun", tunDeviceName)) // execCommand(fmt.Sprintf("ip tuntap add dev %s mode tun", tunDeviceName)) // execCommand(fmt.Sprintf("ip addr flush dev %s", tunDeviceName)) fd, err := createTunDevice(tunDeviceName) if err != nil { fmt.Printf("Failed to create tun device: %v\\n", err) return } defer fd.Close() // 配置IP,并打开网卡(否则ping无反应) // ping 同网段其他网卡地址,ping本机的IP是收不到的,流量不经过网卡 execCommand(fmt.Sprintf("ip addr add 192.168.1.100/24 dev %s", tunDeviceName)) execCommand(fmt.Sprintf("ip link set %s up", tunDeviceName)) reader := bufio.NewReader(fd) for { data := make(\[\]byte, 4096) n, err := reader.Read(data) if err != nil { fmt.Printf("Error reading from tun device: %v\\n", err) break } fmt.Println(data\[0:n\]) } } \`\`\`