Реализация ICMP ping в Go
возможно ли реализовать ICMP ping в Go? Альтернативой является развилка процесса "ping", но я бы предпочел записать его в Go.
2 ответов
В настоящее время функция ICMP Echo (Ping) не поддерживается в пакете Go net.
нет поддержки для отправки ICMP эхо-запрос. Вы должны добавить поддержка пакета net. пинг
следующий код показывает, как выполнить пинг по IPv4 с помощью сырых сокетов (требует прав root):
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)
}
}
на примере кода найти здесь: https://godoc.org/golang.org/x/net/icmp#PacketConn
чтобы выполнить ping из Linux как непривилегированный пользователь, см. этот пост