mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 03:25:35 +00:00
a16a793605
iOS doesn't let you run subprocesses, which means we can't use netstat to get routing information. Instead, use syscalls and grub around in the results. We keep the old netstat version around, both for use in non-cgo builds, and for use testing the syscall-based version. Note that iOS doesn't ship route.h, so we include a copy here from the macOS 10.15 SDK (which is itself unchanged from the 10.14 SDK). I have tested manually that this yields the correct gateway IP address on my own macOS and iOS devices. More coverage would be most welcome. Signed-off-by: Josh Bleecher Snyder <josharian@gmail.com>
70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package interfaces
|
|
|
|
import (
|
|
"os/exec"
|
|
|
|
"go4.org/mem"
|
|
"inet.af/netaddr"
|
|
"tailscale.com/util/lineread"
|
|
"tailscale.com/version"
|
|
)
|
|
|
|
/*
|
|
Parse out 10.0.0.1 from:
|
|
|
|
$ netstat -r -n -f inet
|
|
Routing tables
|
|
|
|
Internet:
|
|
Destination Gateway Flags Netif Expire
|
|
default 10.0.0.1 UGSc en0
|
|
default link#14 UCSI utun2
|
|
10/16 link#4 UCS en0 !
|
|
10.0.0.1/32 link#4 UCS en0 !
|
|
...
|
|
|
|
*/
|
|
func likelyHomeRouterIPDarwinExec() (ret netaddr.IP, ok bool) {
|
|
if version.IsMobile() {
|
|
// Don't try to do subprocesses on iOS. Ends up with log spam like:
|
|
// kernel: "Sandbox: IPNExtension(86580) deny(1) process-fork"
|
|
// This is why we have likelyHomeRouterIPDarwinSyscall.
|
|
return ret, false
|
|
}
|
|
cmd := exec.Command("/usr/sbin/netstat", "-r", "-n", "-f", "inet")
|
|
stdout, err := cmd.StdoutPipe()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if err := cmd.Start(); err != nil {
|
|
return
|
|
}
|
|
defer cmd.Wait()
|
|
|
|
var f []mem.RO
|
|
lineread.Reader(stdout, func(lineb []byte) error {
|
|
line := mem.B(lineb)
|
|
if !mem.Contains(line, mem.S("default")) {
|
|
return nil
|
|
}
|
|
f = mem.AppendFields(f[:0], line)
|
|
if len(f) < 3 || !f[0].EqualString("default") {
|
|
return nil
|
|
}
|
|
ipm, flagsm := f[1], f[2]
|
|
if !mem.Contains(flagsm, mem.S("G")) {
|
|
return nil
|
|
}
|
|
ip, err := netaddr.ParseIP(string(mem.Append(nil, ipm)))
|
|
if err == nil && isPrivateIP(ip) {
|
|
ret = ip
|
|
}
|
|
return nil
|
|
})
|
|
return ret, !ret.IsZero()
|
|
}
|