我正在尝试将小型traceroute实用程序作为某些跨平台项目的一部分。但是我发现在Windows下,尽管我在Wireshark中看到了这些数据包,但Go在原始icmp套接字上看不到任何TTL超出消息。
这里是通过* nix并在Windows下失败的完整测试:
package probes
import (
"fmt"
"net"
"testing"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"time"
)
func TestTtlExceed(t *testing.T) {
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatalf("Cannot listen: %s", err.Error())
}
defer conn.Close()
go listen(conn, t)
msg := icmp.Message{
Code: 0,
Body: &icmp.Echo{
Seq: 1,
ID: 1,
Data: []byte{'t','e','s','t'},
},
Type:ipv4.ICMPTypeEcho,
}
wbuf, err := msg.Marshal(nil)
if err != nil {
t.Fatalf("Failed to marshal: %s", err.Error())
}
conn.IPv4PacketConn().SetTTL(1)
err = conn.SetWriteDeadline(time.Now().Add(time.Second))
if err != nil {
t.Fatalf("Failed to set dl: %s", err.Error())
}
_, err = conn.WriteTo(wbuf, &net.IPAddr{IP:net.ParseIP("8.8.8.8")})
if err != nil {
t.Fatalf("Failed to write: %s", err.Error())
}
time.Sleep(time.Second * 3)
}
func listen(conn *icmp.PacketConn, t *testing.T) {
got := false
conn.SetReadDeadline(time.Now().Add(time.Second * 2))
for {
buf := make([]byte, 256)
n, cm, peer, err := conn.IPv4PacketConn().ReadFrom(buf)
if err != nil {
// t.Fatalf("Error reading: %s", err.Error())
t.Logf("Error reading: %s", err.Error())
break
}
fmt.Printf("Got some: n: %v\tpeer:%s\tcm:%+#v\n", n, peer.String(),cm)
got = true
/*buf := make([]byte, 256)
n, peer, err := conn.ReadFrom(buf)
if err != nil {
t.Fatalf("Listen failed: %s\n", err.Error())
return
}
fmt.Printf("icmp: got\n")
parsed, err := icmp.ParseMessage(1, buf[:n])
if err != nil {
t.Fatalf("Failed to parse icmp message: %s", err.Error())
return
}
fmt.Printf("Got message from %s: %+#v\n", peer.String(), parsed)*/
}
if !got {
t.Fatalf("Got nothing from conn")
}
}
关于Windows icmp原始套接字有什么问题的任何想法吗?