func Pinger(address *net.IPAddr, timeout time.Duration) error { var ( c *net.IPConn err error ) v6 := address.IP.To4() == nil if v6 { c, err = net.DialIP("ip6:ipv6-icmp", nil, address) } else { c, err = net.DialIP("ip4:icmp", nil, address) } if err != nil { return err } c.SetDeadline(time.Now().Add(timeout)) defer c.Close() typ := icmpv4EchoRequest if v6 { typ = icmpv6EchoRequest } xid, xseq := os.Getpid()&0xffff, 1 wb, err := (&icmpMessage{ Type: typ, Code: 0, Body: &icmpEcho{ ID: xid, Seq: xseq, Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), }, }).Marshal() if err != nil { return err } if _, err = c.Write(wb); err != nil { return err } var m *icmpMessage rb := make([]byte, 20+len(wb)) for { if _, err = c.Read(rb); err != nil { return err } if !v6 { rb = ipv4Payload(rb) } if m, err = parseICMPMessage(rb); err != nil { return err } switch m.Type { case icmpv4EchoRequest, icmpv6EchoRequest: continue } break } return nil }