func (p *Pinger) listen(netProto string, source string) *icmp.PacketConn { conn, err := icmp.ListenPacket(netProto, source) if err != nil { p.mu.Lock() p.ctx.err = err p.mu.Unlock() p.debugln("Run(): close(p.ctx.done)") close(p.ctx.done) return nil } return conn }
func ExamplePacketConn_nonPrivilegedPing() { switch runtime.GOOS { case "darwin": case "linux": log.Println("you may need to adjust the net.ipv4.ping_group_range kernel state") default: log.Println("not supported on", runtime.GOOS) return } c, err := icmp.ListenPacket("udp6", "fe80::1%en0") if err != nil { log.Fatal(err) } defer c.Close() wm := icmp.Message{ Type: ipv6.ICMPTypeEchoRequest, 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.UDPAddr{IP: net.ParseIP("ff02::1"), Zone: "en0"}); err != nil { log.Fatal(err) } rb := make([]byte, 1500) n, peer, err := c.ReadFrom(rb) if err != nil { log.Fatal(err) } rm, err := icmp.ParseMessage(58, rb[:n]) if err != nil { log.Fatal(err) } switch rm.Type { case ipv6.ICMPTypeEchoReply: log.Printf("got reflection from %v", peer) default: log.Printf("got %+v; want echo reply", rm) } }
func ExamplePacketConn_nonPrivilegedPing() { c, err := icmp.ListenPacket("udp6", "fe80::1%en0") if err != nil { log.Fatal(err) } defer c.Close() wm := icmp.Message{ Type: ipv6.ICMPTypeEchoRequest, 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.UDPAddr{IP: net.ParseIP("ff02::1"), Zone: "en0"}); err != nil { log.Fatal(err) } rb := make([]byte, 1500) n, peer, err := c.ReadFrom(rb) if err != nil { log.Fatal(err) } rm, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]) if err != nil { log.Fatal(err) } switch rm.Type { case ipv6.ICMPTypeEchoReply: log.Printf("got reflection from %v", peer) default: log.Printf("got %+v; want echo reply", rm) } }
func TestPingGoogle(t *testing.T) { if testing.Short() { t.Skip("to avoid external network") } switch runtime.GOOS { case "darwin": case "linux": t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state") default: t.Skipf("not supported on %s", runtime.GOOS) } m, ok := nettest.SupportsRawIPSocket() for i, tt := range pingGoogleTests { if tt.network[:2] == "ip" && !ok { t.Log(m) continue } c, err := icmp.ListenPacket(tt.network, tt.address) if err != nil { t.Error(err) continue } defer c.Close() dst, err := googleAddr(c, tt.protocol) if err != nil { t.Error(err) continue } wm := icmp.Message{ Type: tt.mtype, Code: 0, Body: &icmp.Echo{ ID: os.Getpid() & 0xffff, Seq: 1 << uint(i), Data: []byte("HELLO-R-U-THERE"), }, } wb, err := wm.Marshal(nil) if err != nil { t.Error(err) continue } if n, err := c.WriteTo(wb, dst); err != nil { t.Error(err, dst) continue } else if n != len(wb) { t.Errorf("got %v; want %v", n, len(wb)) continue } rb := make([]byte, 1500) n, peer, err := c.ReadFrom(rb) if err != nil { t.Error(err) continue } rm, err := icmp.ParseMessage(tt.protocol, rb[:n]) if err != nil { t.Error(err) continue } switch rm.Type { case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply: t.Logf("got reflection from %v", peer) default: t.Errorf("got %+v; want echo reply", rm) } } }
func doPing(tt pingTest, seq int) error { c, err := icmp.ListenPacket(tt.network, tt.address) if err != nil { return err } defer c.Close() dst, err := googleAddr(c, tt.protocol) if err != nil { return err } if tt.network != "udp6" && tt.protocol == iana.ProtocolIPv6ICMP { var f ipv6.ICMPFilter f.SetAll(true) f.Accept(ipv6.ICMPTypeDestinationUnreachable) f.Accept(ipv6.ICMPTypePacketTooBig) f.Accept(ipv6.ICMPTypeTimeExceeded) f.Accept(ipv6.ICMPTypeParameterProblem) f.Accept(ipv6.ICMPTypeEchoReply) if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil { return err } } wm := icmp.Message{ Type: tt.mtype, Code: 0, Body: &icmp.Echo{ ID: os.Getpid() & 0xffff, Seq: 1 << uint(seq), Data: []byte("HELLO-R-U-THERE"), }, } wb, err := wm.Marshal(nil) if err != nil { return err } if n, err := c.WriteTo(wb, dst); err != nil { return err } else if n != len(wb) { return fmt.Errorf("got %v; want %v", n, len(wb)) } rb := make([]byte, 1500) if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { return err } n, peer, err := c.ReadFrom(rb) if err != nil { return err } rm, err := icmp.ParseMessage(tt.protocol, rb[:n]) if err != nil { return err } switch rm.Type { case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply: return nil default: return fmt.Errorf("got %+v from %v; want echo reply", rm, peer) } }