From 06ddb3e0a7265a8a054b9b225a2d9fb994535cde Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Mon, 25 Aug 2025 10:18:22 +0800 Subject: [PATCH] ping: Add comments --- internal/gtcpip/header/ipv4.go | 8 ++++---- ping/cmsg_windows.go | 7 ++++--- ping/ping.go | 3 +++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/internal/gtcpip/header/ipv4.go b/internal/gtcpip/header/ipv4.go index 624166c..8253936 100644 --- a/internal/gtcpip/header/ipv4.go +++ b/internal/gtcpip/header/ipv4.go @@ -335,7 +335,7 @@ func (b IPv4) FragmentOffset() uint16 { } func (b IPv4) FragmentOffsetDarwinRaw() uint16 { - return binary.NativeEndian.Uint16(b[flagsFO:]) << 3 + return common.NativeEndian.Uint16(b[flagsFO:]) << 3 } // TotalLength returns the "total length" field of the IPv4 header. @@ -344,7 +344,7 @@ func (b IPv4) TotalLength() uint16 { } func (b IPv4) TotalLengthDarwinRaw() uint16 { - return binary.NativeEndian.Uint16(b[IPv4TotalLenOffset:]) + uint16(b.HeaderLength()) + return common.NativeEndian.Uint16(b[IPv4TotalLenOffset:]) + uint16(b.HeaderLength()) } // Checksum returns the checksum field of the IPv4 header. @@ -441,7 +441,7 @@ func (b IPv4) SetTotalLength(totalLength uint16) { } func (b IPv4) SetTotalLengthDarwinRaw(totalLength uint16) { - binary.NativeEndian.PutUint16(b[IPv4TotalLenOffset:], totalLength) + common.NativeEndian.PutUint16(b[IPv4TotalLenOffset:], totalLength) } // SetChecksum sets the checksum field of the IPv4 header. @@ -458,7 +458,7 @@ func (b IPv4) SetFlagsFragmentOffset(flags uint8, offset uint16) { func (b IPv4) SetFlagsFragmentOffsetDarwinRaw(flags uint8, offset uint16) { v := (uint16(flags) << 13) | (offset >> 3) - binary.NativeEndian.PutUint16(b[flagsFO:], v) + common.NativeEndian.PutUint16(b[flagsFO:], v) } // SetID sets the identification field. diff --git a/ping/cmsg_windows.go b/ping/cmsg_windows.go index be5be9b..07c322c 100644 --- a/ping/cmsg_windows.go +++ b/ping/cmsg_windows.go @@ -1,10 +1,11 @@ package ping import ( - "encoding/binary" "fmt" "unsafe" + "github.com/sagernet/sing/common" + "golang.org/x/net/ipv6" "golang.org/x/sys/windows" ) @@ -36,9 +37,9 @@ func parseIPv6ControlMessage(cmsg []byte) (*ipv6.ControlMessage, error) { } switch cmsghdr.Type { case IPV6_TCLASS: - controlMessage.TrafficClass = int(binary.NativeEndian.Uint32(cmsg[alignedSizeofCmsghdr : alignedSizeofCmsghdr+4])) + controlMessage.TrafficClass = int(common.NativeEndian.Uint32(cmsg[alignedSizeofCmsghdr : alignedSizeofCmsghdr+4])) case IPV6_HOPLIMIT: - controlMessage.HopLimit = int(binary.NativeEndian.Uint32(cmsg[alignedSizeofCmsghdr : alignedSizeofCmsghdr+4])) + controlMessage.HopLimit = int(common.NativeEndian.Uint32(cmsg[alignedSizeofCmsghdr : alignedSizeofCmsghdr+4])) } cmsg = cmsg[msgSize:] } diff --git a/ping/ping.go b/ping/ping.go index f3f661c..e8b6ef5 100644 --- a/ping/ping.go +++ b/ping/ping.go @@ -160,6 +160,9 @@ func (c *Conn) ReadIP(buffer *buf.Buffer) error { if !c.destination.Is6() { ipHdr := header.IPv4(buffer.Bytes()) if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { + // MacOS have different TotalLen and FragOff in ipv4 header from socket api: + // https://stackoverflow.com/questions/13829712/mac-changes-ip-total-length-field/15881825#15881825 + // but in the tun api still same data format as other system ipHdr.SetTotalLength(ipHdr.TotalLengthDarwinRaw()) ipHdr.SetFlagsFragmentOffset(ipHdr.FlagsDarwinRaw(), ipHdr.FragmentOffsetDarwinRaw()) }