我正在研究一个简单的项目,该项目在 tun 接口上侦听并修改数据包,然后将它们重新发送到真实接口。
我已经尝试过songgao/water
,pkg/tuntap
甚至根据一些浮动的 C 代码编写自己的代码,但无论我尝试什么,我都无法接收 TCP 数据包(ICMP/UDP 工作正常)。
我觉得我错过了一些非常明显的东西,但我无法为我的生活弄清楚......
代码:_
package main
import (
"log"
"os"
"os/exec"
"golang.org/x/net/ipv4"
"github.com/songgao/water"
)
const (
// I use TUN interface, so only plain IP packet, no ethernet header + mtu is set to 1300
BUFFERSIZE = 1600
MTU = "1300"
)
func main() {
iface, err := water.New(water.Config{})
fatalIf(err)
log.Printf("tun interface: %s", iface.Name())
runBin("/bin/ip", "link", "set", "dev", iface.Name(), "mtu", MTU)
runBin("/bin/ip", "addr", "add", "10.2.0.10/24", "dev", iface.Name())
runBin("/bin/ip", "link", "set", "dev", iface.Name(), "up")
buf := make([]byte, BUFFERSIZE)
for {
n, err := iface.Read(buf)
if err != nil {
log.Fatal(err)
}
header, _ := ipv4.ParseHeader(buf[:n])
log.Printf("isTCP: %v, header: %s", header.Protocol == 6, header)
}
}
func fatalIf(err error) {
if err != nil {
log.Fatal(err)
}
}
func runBin(bin string, args ...string) {
cmd := exec.Command(bin, args...)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
fatalIf(cmd.Run())
}