mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +00:00
e101d8396d
Build tags have been updated to build native Apple M1 binaries, existing build tags for ios have been changed from darwin,arm64 to ios,arm64. With this change, running go build cmd/tailscale{,d}/tailscale{,d}.go on an Apple machine with the new processor works and resulting binaries show the expected architecture, e.g. tailscale: Mach-O 64-bit executable arm64. Tested using go version go1.16beta1 darwin/arm64. Updates #943 Signed-off-by: moncho <50428+moncho@users.noreply.github.com>
145 lines
3.1 KiB
Go
145 lines
3.1 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.
|
|
|
|
// +build go1.16,!ios !go1.16,!darwin !go1.16,!arm64
|
|
|
|
package portlist
|
|
|
|
import (
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func parsePort(s string) int {
|
|
// a.b.c.d:1234 or [a:b:c:d]:1234
|
|
i1 := strings.LastIndexByte(s, ':')
|
|
// a.b.c.d.1234 or [a:b:c:d].1234
|
|
i2 := strings.LastIndexByte(s, '.')
|
|
|
|
i := i1
|
|
if i2 > i {
|
|
i = i2
|
|
}
|
|
if i < 0 {
|
|
// no match; weird
|
|
return -1
|
|
}
|
|
|
|
portstr := s[i+1:]
|
|
if portstr == "*" {
|
|
return 0
|
|
}
|
|
|
|
port, err := strconv.ParseUint(portstr, 10, 16)
|
|
if err != nil {
|
|
// invalid port; weird
|
|
return -1
|
|
}
|
|
|
|
return int(port)
|
|
}
|
|
|
|
func isLoopbackAddr(s string) bool {
|
|
return strings.HasPrefix(s, "127.0.0.1:") || strings.HasPrefix(s, "127.0.0.1.")
|
|
}
|
|
|
|
type nothing struct{}
|
|
|
|
// Lowest common denominator parser for "netstat -na" format.
|
|
// All of Linux, Windows, and macOS support -na and give similar-ish output
|
|
// formats that we can parse without special detection logic.
|
|
// Unfortunately, options to filter by proto or state are non-portable,
|
|
// so we'll filter for ourselves.
|
|
func parsePortsNetstat(output string) List {
|
|
m := map[Port]nothing{}
|
|
lines := strings.Split(string(output), "\n")
|
|
|
|
var lastline string
|
|
var lastport Port
|
|
for _, line := range lines {
|
|
trimline := strings.TrimSpace(line)
|
|
cols := strings.Fields(trimline)
|
|
if len(cols) < 1 {
|
|
continue
|
|
}
|
|
protos := strings.ToLower(cols[0])
|
|
var proto, laddr, raddr string
|
|
if strings.HasPrefix(protos, "tcp") {
|
|
if len(cols) < 4 {
|
|
continue
|
|
}
|
|
proto = "tcp"
|
|
laddr = cols[len(cols)-3]
|
|
raddr = cols[len(cols)-2]
|
|
state := cols[len(cols)-1]
|
|
if !strings.HasPrefix(state, "LISTEN") {
|
|
// not interested in non-listener sockets
|
|
continue
|
|
}
|
|
if isLoopbackAddr(laddr) {
|
|
// not interested in loopback-bound listeners
|
|
continue
|
|
}
|
|
} else if strings.HasPrefix(protos, "udp") {
|
|
if len(cols) < 3 {
|
|
continue
|
|
}
|
|
proto = "udp"
|
|
laddr = cols[len(cols)-2]
|
|
raddr = cols[len(cols)-1]
|
|
if isLoopbackAddr(laddr) {
|
|
// not interested in loopback-bound listeners
|
|
continue
|
|
}
|
|
} else if protos[0] == '[' && len(trimline) > 2 {
|
|
// Windows: with netstat -nab, appends a line like:
|
|
// [description]
|
|
// after the port line.
|
|
p := lastport
|
|
delete(m, lastport)
|
|
proc := trimline[1 : len(trimline)-1]
|
|
if proc == "svchost.exe" && lastline != "" {
|
|
p.Process = lastline
|
|
} else {
|
|
if strings.HasSuffix(proc, ".exe") {
|
|
p.Process = proc[:len(proc)-4]
|
|
} else {
|
|
p.Process = proc
|
|
}
|
|
}
|
|
m[p] = nothing{}
|
|
} else {
|
|
// not interested in other protocols
|
|
lastline = trimline
|
|
continue
|
|
}
|
|
|
|
lport := parsePort(laddr)
|
|
rport := parsePort(raddr)
|
|
if rport != 0 || lport <= 0 {
|
|
// not interested in "connected" sockets
|
|
continue
|
|
}
|
|
|
|
p := Port{
|
|
Proto: proto,
|
|
Port: uint16(lport),
|
|
}
|
|
m[p] = nothing{}
|
|
lastport = p
|
|
lastline = ""
|
|
}
|
|
|
|
l := []Port{}
|
|
for p := range m {
|
|
l = append(l, p)
|
|
}
|
|
sort.Slice(l, func(i, j int) bool {
|
|
return (&l[i]).lessThan(&l[j])
|
|
})
|
|
|
|
return l
|
|
}
|