第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

Golang 學(xué)習(xí)筆記——tap+udp

標(biāo)簽:
Go
  • 如何连接两台机器上的虚拟网卡?
    图片描述
    要连接两块虚拟网卡,可以在 eth0 之间建立 udp 通信,把 tap 网卡上的以太帧通过 udp 发送到远端,再转发到远端 tap 网卡,最后原路返回,这样实现互通。最终拓扑为
    图片描述

环境准备

两台虚拟机:

  • host5 网卡:enp0s3 IP:192.168.1.5
  • host7 网卡:enp0s3 IP:192.168.1.7

创建 tap

  • 命令行创建
sudo ip tuntap add tap0 mode tap
sudo ifconfig tap0 10.0.1.1/24 up
  • 程序创建
    • 通过 newTap 方法创建网卡
    • 通过 runCommand 调用 shell 命令配置 ip
import (
	"fmt"
	"github.com/songgao/water"
	"os/exec"
	"strings"
)

func main() {
	iface := newTap()
	runCommand("ifconfig", iface.Name(), " 10.0.0.1/24", "up")

	select {}
}

func newTap() *water.Interface {
	tapconfig := water.Config{
		DeviceType: water.TAP,
		PlatformSpecificParams: water.PlatformSpecificParams{
			Name: "tap0",
		},
	}

	iface, err := water.New(tapconfig)
	if err != nil {
		fmt.Printf("创建失败:%v \n", err)
	}
	return iface
}

func runCommand(args ...string) string {
	cmdStr := strings.Join(args, " ")
	cmd := exec.Command("/bin/sh", "-c", cmdStr)
	opBytes, err := cmd.Output()
	if err != nil {
		fmt.Println(err)
		return ""
	}
	return string(opBytes)
}

创建 udp socket

  • raddr 远端地址
  • udp 客户端和服务端监听同样的端口

	
func newUDPConn(port int) *net.UDPConn {
	srcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: port}
	conn, err := net.ListenUDP("udp", srcAddr)
	if err != nil {
		fmt.Println("udp启动失败!", err)
		os.Exit(1)
	}
	fmt.Println("udp启动成功")
	return conn
}

读取数据

  • readTapToUdp 读取 tap,写入 udp
  • readUdpToTap 读取 udp,写入 tap
  • raddr udp 远端地址

func readTapToUdp(conn *net.UDPConn, iface *water.Interface, raddr *net.UDPAddr) {
	buf := make([]byte, 65536)

	for {
		n, err := iface.Read(buf)
		if err != nil {
			fmt.Printf("tap read error: %v\n", err)
			time.Sleep(time.Millisecond * 10)
			continue
		}
		fmt.Printf("tap read num: %v, raddr: %v\n", n, raddr)

		if _, err := conn.WriteToUDP(buf[:n], raddr); err != nil {
			fmt.Printf("udp write error: %v\n", err)
			time.Sleep(time.Millisecond)
			continue
		}
	}
}

func readUdpToTap(conn *net.UDPConn, iface *water.Interface) {
	buf := make([]byte, 65536)
	for {
		n, raddr, err := conn.ReadFromUDP(buf)
		if err != nil {
			fmt.Printf("udp read error: %v\n", err)
			time.Sleep(time.Millisecond * 10)
			continue
		}
		fmt.Printf("udp read num: %v, raddr: %v\n", n, raddr)

		if _, err := iface.Write(buf[:n]); err != nil {
			fmt.Printf("tun write error: %v\n", err)
		}
	}
}

增加启动参数

  • remote 为远端 IP
  • port 被监听的端口
  • tapIp 给 tap 设置的 IP
var (
	remote string
	port int
	tapIp string
)

func main() {
	flag.StringVar(&remote, "r", "", "")
	flag.IntVar(&port, "p", 9000, "")
	flag.StringVar(&tapIp, "ip", "", "")
	flag.Parse()
	addr := fmt.Sprintf("%s:%d", remote, port)
	fmt.Println("remote address:", addr)

	raddr, err := net.ResolveUDPAddr("udp", addr)
	if err != nil {
		fmt.Println("地址解析失败!", err)
		os.Exit(1)
	}
	
	iface := newTap()
	runCommand("ifconfig", iface.Name(), tapIp, "up")
	defer iface.Close()

	conn := newUDPConn(port)

	defer conn.Close()
	go readTapToUdp(conn, iface, raddr)
	readUdpToTap(conn, iface)
}

运行

# 编译
go build tap.go
# host7
sudo ./tap -r 192.168.1.5 -ip 10.0.0.1/24
# host5
sudo ./tap -r 192.168.1.7 -ip 10.0.0.2/24

结果

图片描述

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶(hù)
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專(zhuān)欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消