duanjing1276 2019-05-06 08:09
浏览 98

icmp.PacketConn在Windows下看不到TTL超过消息

I'm trying to implement small traceroute utility as part of some crossplatform project. But I've found that under Windows, Go doesn't see any TTL exceed messages on raw icmp socket, despite the fact that I see those packets in wireshark.

Here is a full test that passes under *nix and fails under 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, peer.String(),cm)
        got = true
        /*buf := make([]byte, 256)
        n, peer, err := conn.ReadFrom(buf)
        if err != nil {
            t.Fatalf("Listen failed: %s
", err.Error())
            return
        }
        fmt.Printf("icmp: got
")
        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
", peer.String(), parsed)*/
    }
    if !got {
        t.Fatalf("Got nothing from conn")
    }
}

Any ideas about what's wrong with windows icmp raw socket?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 STM32驱动继电器
    • ¥15 Windows server update services
    • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
    • ¥15 模糊pid与pid仿真结果几乎一样
    • ¥15 java的GUI的运用
    • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
    • ¥15 怎么配置广告联盟瀑布流
    • ¥15 Rstudio 保存代码闪退
    • ¥20 win系统的PYQT程序生成的数据如何放入云服务器阿里云window版?
    • ¥50 invest生境质量模块