improve: rootless trace on macOS

This commit is contained in:
bobo liu
2023-06-03 16:50:21 +08:00
parent eb64f68663
commit 2bac716bd7
6 changed files with 63 additions and 3 deletions

View File

@@ -12,6 +12,7 @@ import (
"sync"
"time"
"github.com/xgadget-lab/nexttrace/trace/internal"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
@@ -64,7 +65,7 @@ func (t *ICMPTracer) Execute() (*Result, error) {
var err error
t.icmpListen, err = net.ListenPacket("ip4:1", t.SrcAddr)
t.icmpListen, err = internal.ListenICMP("ip4:1", t.SrcAddr)
if err != nil {
return &t.res, err
}

View File

@@ -10,6 +10,7 @@ import (
"sync"
"time"
"github.com/xgadget-lab/nexttrace/trace/internal"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv6"
@@ -65,7 +66,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
var err error
t.icmpListen, err = net.ListenPacket("ip6:58", t.SrcAddr)
t.icmpListen, err = internal.ListenICMP("ip6:58", t.SrcAddr)
if err != nil {
return &t.res, err
}

View File

@@ -0,0 +1,49 @@
//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",
}
)
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
}
}
}

View File

View File

@@ -0,0 +1,9 @@
//go:build !darwin
package internal
import "net"
func ListenICMP(network string, laddr string) (net.PacketConn, error) {
return net.ListenPacket(network, laddr)
}

View File

@@ -2,12 +2,12 @@ package trace
import (
"errors"
"github.com/xgadget-lab/nexttrace/util"
"net"
"sync"
"time"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/util"
)
var (