mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
//go:build darwin
|
|
|
|
package internal
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"os"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
//go:linkname internetSocket net.internetSocket
|
|
func internetSocket(ctx context.Context, net string, laddr, raddr interface{}, sotype, proto int, mode string, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd unsafe.Pointer, err error)
|
|
|
|
//go:linkname newIPConn net.newIPConn
|
|
func newIPConn(fd unsafe.Pointer) *net.IPConn
|
|
|
|
var (
|
|
errUnknownNetwork = errors.New("unknown network type")
|
|
|
|
networkMap = map[string]string{
|
|
"ip4:icmp": "udp4",
|
|
"ip4:1": "udp4",
|
|
"ip6:icmp": "udp6",
|
|
"ip6:58": "udp6",
|
|
}
|
|
)
|
|
|
|
// 会造成指定出口IP功能不可使用
|
|
func ListenICMP(network string, laddr string) (net.PacketConn, error) {
|
|
if os.Getuid() == 0 { // root
|
|
return net.ListenPacket(network, laddr)
|
|
} else {
|
|
if nw, ok := networkMap[network]; ok {
|
|
proto := syscall.IPPROTO_ICMP
|
|
if nw == "udp6" {
|
|
proto = syscall.IPPROTO_ICMPV6
|
|
}
|
|
isock, err := internetSocket(context.Background(), nw, nil, nil, syscall.SOCK_DGRAM, proto, "listen", nil)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return newIPConn(isock), nil
|
|
} else {
|
|
return nil, errUnknownNetwork
|
|
}
|
|
}
|
|
}
|