你能在 Mac 上将数据包从 TUN 转发到路由器吗?

你能在 Mac 上将数据包从 TUN 转发到路由器吗?

我正在用我的一个玩具数据包嗅探器拦截数据包,它只是将所有流量从设备上拉下来TUN。我在我的 Mac 上通过以下方式设置了到 TUN 的默认路由:

sudo route -n add default 10.1.0.10

10.1.0.10设备的 IP 在哪里utun5。虽然我可以看到数据包通过我的程序,但我只想打印它们然后将它们转发到路由器。例如,如果我要curl google.comping yahoo.com我会看到数据包,但客户端仍会像往常一样获得预期的响应。

我觉得在 Linux 上,通过 IP 转发、NAT 以及通过 iproute2 实现这一点并不太难iptables。在 Mac 上,我就是搞不清楚这应该如何工作。任何帮助或阅读都非常感谢。

从编码方面来看,我使用 Go 和water库来简化 tun 设备的创建。

这是一个基本的实现:

package main

import (
    "log"
    "net"

    "github.com/songgao/water"
    "golang.org/x/net/ipv4"
)

func main() {
    ifce, err := water.New(water.Config{
        DeviceType: water.TUN,
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("Interface Name: %s\n", ifce.Name())

    packet := make([]byte, 2000)

    // Replace "en0" with your internet-facing network interface name
    internetInterface, err := net.InterfaceByName("en0")
    if err != nil {
        log.Fatal(err)
    }

    conn, err := net.ListenPacket("ip4:4", "0.0.0.0") // Listen for IPv4 packets
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    rawConn, err := ipv4.NewRawConn(conn)
    if err != nil {
        log.Fatal(err)
    }

    for {
        n, err := ifce.Read(packet)
        if err != nil {
            log.Fatal(err)
        }

        header, err := ipv4.ParseHeader(packet[:n])
        if err != nil {
            log.Printf("Error parsing IPv4 header: %v", err)
            continue
        }

        cm := &ipv4.ControlMessage{
            IfIndex: internetInterface.Index,
        }

        err = rawConn.WriteTo(header, packet[header.Len:n], cm)
        if err != nil {
            log.Printf("Error writing packet to raw socket: %v", err)
        }
    }
}

相关内容