Czy można wdrożyć ping ICMP w Go? Alternatywą jest rozwidlenie procesu pingowania, ale wolę napisać go w Go.Implementacja ping ICMP w Go
Odpowiedz
Obecnie funkcja ICMP Echo (Ping) nie jest obsługiwana w pakiecie Go net.
Brak wsparcia dla wysyłania żądań echa ICMP . Musisz dodać obsługę do sieci pakietowej. ping
Poniższy kod pokazuje jak wykonać ping nad IPv4 przy użyciu gniazda surowego (wymaga privs 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)
}
}
kod oparty na przykład znaleźć tutaj: https://godoc.org/golang.org/x/net/icmp#PacketConn
Na zamówienie do pingowania z Linuksa jako nieuprzywilejowany użytkownik, zobacz this post
Obecnie numer IANA dla ICMP (1) nie jest dostępny za pośrednictwem 'iana.ProtocolICMP', ale można uzyskać do niego dostęp poprzez' ipv4. ICMPTypeEcho.Protocol() '. Pakiet 'golang.org/x/net/internal/iana' jest wewnętrzny, gdy jest używany kompilator go 1.8, który mówi:' użycie wewnętrznego pakietu niedozwolonego 'por .: https://godoc.org/golang.org/x /net/ipv4#ICMPType.Protocol – TPPZ
Również cf. https://godoc.org/golang.org/x/net/internal/iana – TPPZ
Teraz (od końca maja 2010 r.) Go obsługuje nieprzetworzone gniazda (zobacz typ net.IPConn) - co oznacza, że możesz ementuj samemu ping - a na przykład https://code.google.com/p/go/source/browse/src/pkg/net/ipraw_test.go jest to – nos
Link przez @nos już nie działa. Nowy adres URL powinien być: https://golang.org/src/net/ipraw_test.go – TheHippo