(network string, ip net.IP, timeout time.Duration, echo icmpMsg)
| 159 | } |
| 160 | |
| 161 | func exchangeICMPEcho(network string, ip net.IP, timeout time.Duration, echo icmpMsg) error { |
| 162 | c, err := net.ListenPacket(network, "") |
| 163 | if err != nil { |
| 164 | return err |
| 165 | } |
| 166 | defer c.Close() |
| 167 | |
| 168 | _, err = c.WriteTo(echo, &net.IPAddr{IP: ip}) |
| 169 | if err != nil { |
| 170 | return err |
| 171 | } |
| 172 | |
| 173 | c.SetDeadline(time.Now().Add(timeout)) |
| 174 | reply := make([]byte, 256) |
| 175 | for { |
| 176 | _, addr, err := c.ReadFrom(reply) |
| 177 | if err != nil { |
| 178 | return err |
| 179 | } |
| 180 | if !ip.Equal(net.ParseIP(addr.String())) { |
| 181 | continue |
| 182 | } |
| 183 | if reply[0] != ICMP4_ECHO_REPLY && reply[0] != ICMP6_ECHO_REPLY { |
| 184 | continue |
| 185 | } |
| 186 | xid, xseqnum, _ := parseICMPEchoReply(echo) |
| 187 | rid, rseqnum, rchksum := parseICMPEchoReply(reply) |
| 188 | if rid != xid || rseqnum != xseqnum { |
| 189 | continue |
| 190 | } |
| 191 | if reply[0] == ICMP4_ECHO_REPLY { |
| 192 | cs := icmpChecksum(reply) |
| 193 | if cs != 0 { |
| 194 | return fmt.Errorf("Bad ICMP checksum: %x", rchksum) |
| 195 | } |
| 196 | } |
| 197 | // TODO(angusc): Validate checksum for IPv6 |
| 198 | break |
| 199 | } |
| 200 | return nil |
| 201 | } |
no test coverage detected