mirror of
https://github.com/go-ping/ping.git
synced 2025-06-24 21:21:40 +00:00
fix: Non-privileged (UDP) ping response parsing for OSes not supporting STRIPHDR sock option
Signed-off-by: Gaius <gaius.qi@gmail.com>
This commit is contained in:
parent
b89bb75386
commit
62e11a6da0
21
ping.go
21
ping.go
@ -49,7 +49,6 @@
|
|||||||
// it calls the OnFinish callback.
|
// it calls the OnFinish callback.
|
||||||
//
|
//
|
||||||
// For a full ping example, see "cmd/ping/ping.go".
|
// For a full ping example, see "cmd/ping/ping.go".
|
||||||
//
|
|
||||||
package ping
|
package ping
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -580,7 +579,8 @@ func (p *Pinger) recvICMP(
|
|||||||
case <-p.done:
|
case <-p.done:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
bytes := make([]byte, p.getMessageLength())
|
messageLength := p.getMessageLength()
|
||||||
|
bytes := make([]byte, messageLength)
|
||||||
if err := conn.SetReadDeadline(time.Now().Add(delay)); err != nil {
|
if err := conn.SetReadDeadline(time.Now().Add(delay)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -598,10 +598,25 @@ func (p *Pinger) recvICMP(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// syscall.SetsockoptInt dose not work with sysIP_STRIPHDR on the darwin,
|
||||||
|
// we need to check the bytes, if there is an IP header, we needs to strip it.
|
||||||
|
// Refer to https://go.googlesource.com/net/+/master/icmp/listen_posix.go#75.
|
||||||
|
if !p.Privileged() && n >= messageLength {
|
||||||
|
if p.ipv4 {
|
||||||
|
if hdr, err := ipv4.ParseHeader(bytes); err == nil && hdr != nil && hdr.TotalLen == n && hdr.Len == ipv4.HeaderLen {
|
||||||
|
bytes = bytes[ipv4.HeaderLen:]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if hdr, err := ipv6.ParseHeader(bytes); err == nil && hdr.PayloadLen == p.Size && hdr.NextHeader == protocolIPv6ICMP {
|
||||||
|
bytes = bytes[ipv6.HeaderLen:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-p.done:
|
case <-p.done:
|
||||||
return nil
|
return nil
|
||||||
case recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}:
|
case recv <- &packet{bytes: bytes, nbytes: len(bytes), ttl: ttl}:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,22 @@
|
|||||||
|
|
||||||
package ping
|
package ping
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/ipv4"
|
||||||
|
"golang.org/x/net/ipv6"
|
||||||
|
)
|
||||||
|
|
||||||
// Returns the length of an ICMP message.
|
// Returns the length of an ICMP message.
|
||||||
func (p *Pinger) getMessageLength() int {
|
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.
|
// Attempts to match the ID of an ICMP packet.
|
||||||
|
@ -3,9 +3,22 @@
|
|||||||
|
|
||||||
package ping
|
package ping
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/ipv4"
|
||||||
|
"golang.org/x/net/ipv6"
|
||||||
|
)
|
||||||
|
|
||||||
// Returns the length of an ICMP message.
|
// Returns the length of an ICMP message.
|
||||||
func (p *Pinger) getMessageLength() int {
|
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.
|
// Attempts to match the ID of an ICMP packet.
|
||||||
|
Loading…
Reference in New Issue
Block a user