在Go中实现ICMP ping

mar*_*ter 7 sockets ping go

可以在Go中实现ICMP ping吗?另一种方法是分叉'ping'进程,但我宁愿在Go中编写它.

Ian*_*anB 11

以下代码显示如何使用原始套接字执行IPv4 ping(需要root privs):

package main

import (
    "log"
    "net"
    "os"

    "golang.org/x/net/icmp"
    "golang.org/x/net/internal/iana"
    "golang.org/x/net/ipv4"
)

const targetIP = "8.8.8.8"

func main() {
    c, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
    if err != nil {
        log.Fatalf("listen err, %s", err)
    }
    defer c.Close()

    wm := icmp.Message{
        Type: ipv4.ICMPTypeEcho, Code: 0,
        Body: &icmp.Echo{
            ID: os.Getpid() & 0xffff, Seq: 1,
            Data: []byte("HELLO-R-U-THERE"),
        },
    }
    wb, err := wm.Marshal(nil)
    if err != nil {
        log.Fatal(err)
    }
    if _, err := c.WriteTo(wb, &net.IPAddr{IP: net.ParseIP(targetIP)}); err != nil {
        log.Fatalf("WriteTo err, %s", err)
    }

    rb := make([]byte, 1500)
    n, peer, err := c.ReadFrom(rb)
    if err != nil {
        log.Fatal(err)
    }
    rm, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
    if err != nil {
        log.Fatal(err)
    }
    switch rm.Type {
    case ipv4.ICMPTypeEchoReply:
        log.Printf("got reflection from %v", peer)
    default:
        log.Printf("got %+v; want echo reply", rm)
    }
}
Run Code Online (Sandbox Code Playgroud)

代码基于此处的示例:https://godoc.org/golang.org/x/net/icmp#PacketConn

要作为非特权用户从Linux ping,请参阅此文章


pet*_*rSO 5

目前,Go net包中不支持ICMP Echo(Ping)功能.

不支持发送ICMP回应请求.您必须添加对package net的支持.

  • 现在(自2010年5月下旬以来),Go支持原始套接字(请参阅net.IPConn类型) - 这意味着您可以自己实施ping - 并且在https://code.google.com/p/go/source/上有一个ping示例浏览/ src目录/包装/网/ ipraw_test.go (2认同)