diff --git a/.gitignore b/.gitignore index f527a0e..fca34bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /ping /dist +.idea diff --git a/ping.go b/ping.go index ef277ab..002502b 100644 --- a/ping.go +++ b/ping.go @@ -580,7 +580,8 @@ func (p *Pinger) recvICMP( case <-p.done: return nil default: - bytes := make([]byte, p.getMessageLength()) + expectedSize := p.getMessageLength() + bytes := make([]byte, expectedSize) if err := conn.SetReadDeadline(time.Now().Add(delay)); err != nil { return err } @@ -597,7 +598,20 @@ func (p *Pinger) recvICMP( } return err } + // setsockopt sysIP_STRIPHDR may not work, check if we got IP header & need to strip it + if !p.Privileged() && n >= expectedSize { + if p.ipv4 { + if hdr, err := ipv4.ParseHeader(bytes); err == nil && hdr != nil && hdr.TotalLen == n && hdr.Len == ipv4.HeaderLen { + bytes = bytes[hdr.Len:] + } + } else { + if hdr, err := ipv6.ParseHeader(bytes); err == nil && hdr.PayloadLen == p.Size && hdr.NextHeader == protocolIPv6ICMP { + + bytes = bytes[ipv6.HeaderLen:] + } + } + } select { case <-p.done: return nil diff --git a/utils_linux.go b/utils_linux.go index a3e4e8c..30fa8c3 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -3,9 +3,20 @@ package ping +import ( + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + // Returns the length of an ICMP message. func (p *Pinger) getMessageLength() int { - return p.Size + 8 + if p.Privileged() { + return p.Size + 8 + } + if p.ipv4 { + return p.Size + 8 + ipv4.HeaderLen + } + return p.Size + 8 + ipv6.HeaderLen } // Attempts to match the ID of an ICMP packet. diff --git a/utils_other.go b/utils_other.go index d229c41..7d93bcf 100644 --- a/utils_other.go +++ b/utils_other.go @@ -3,9 +3,20 @@ package ping +import ( + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + // Returns the length of an ICMP message. func (p *Pinger) getMessageLength() int { - return p.Size + 8 + if p.Privileged() { + return p.Size + 8 + } + if p.ipv4 { + return p.Size + 8 + ipv4.HeaderLen + } + return p.Size + 8 + ipv6.HeaderLen } // Attempts to match the ID of an ICMP packet.