Implementing ICMP ping in Go
Currently, the ICMP Echo (Ping) function isn't supported in the Go net package.
There's no support for sending ICMP echo requests. You'd have to add support to package net. ping
The following code shows how to perform a ping over IPv4 using a raw socket (requires root privs):
package main
import (
"log"
"net"
"os"
"golang.org/x/net/icmp"
"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(ipv4.ICMPTypeEchoReply.Protocol(), 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)
}
}
Code based on the example found here: https://godoc.org/golang.org/x/net/icmp#PacketConn
In order to ping from Linux as a non-privileged user, see this post