2023-01-27 21:37:20 +00:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
2020-02-05 22:16:58 +00:00
|
|
|
|
2022-11-04 13:41:36 +00:00
|
|
|
//go:build darwin && !ios
|
2022-10-22 04:30:40 +00:00
|
|
|
|
2020-02-05 22:16:58 +00:00
|
|
|
package portlist
|
|
|
|
|
|
|
|
import (
|
2022-11-04 13:41:36 +00:00
|
|
|
"bufio"
|
2021-04-12 16:06:57 +00:00
|
|
|
"encoding/json"
|
2023-05-24 16:52:45 +00:00
|
|
|
"fmt"
|
2022-11-04 13:41:36 +00:00
|
|
|
"strings"
|
2020-02-05 22:16:58 +00:00
|
|
|
"testing"
|
2022-11-04 13:41:36 +00:00
|
|
|
|
|
|
|
"go4.org/mem"
|
2020-02-05 22:16:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestParsePort(t *testing.T) {
|
|
|
|
type InOut struct {
|
|
|
|
in string
|
|
|
|
expect int
|
|
|
|
}
|
|
|
|
tests := []InOut{
|
2021-12-15 16:42:25 +00:00
|
|
|
{"1.2.3.4:5678", 5678},
|
|
|
|
{"0.0.0.0.999", 999},
|
|
|
|
{"1.2.3.4:*", 0},
|
|
|
|
{"5.5.5.5:0", 0},
|
|
|
|
{"[1::2]:5", 5},
|
|
|
|
{"[1::2].5", 5},
|
|
|
|
{"gibberish", -1},
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, io := range tests {
|
2022-11-04 13:41:36 +00:00
|
|
|
got := parsePort(mem.S(io.in))
|
2020-02-05 22:16:58 +00:00
|
|
|
if got != io.expect {
|
|
|
|
t.Fatalf("input:%#v expect:%v got:%v\n", io.in, io.expect, got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-18 03:19:39 +00:00
|
|
|
const netstatOutput = `
|
2020-02-05 22:16:58 +00:00
|
|
|
// macOS
|
|
|
|
tcp4 0 0 *.23 *.* LISTEN
|
2021-04-12 16:06:57 +00:00
|
|
|
tcp6 0 0 *.24 *.* LISTEN
|
|
|
|
tcp4 0 0 *.8185 *.* LISTEN
|
|
|
|
tcp4 0 0 127.0.0.1.8186 *.* LISTEN
|
|
|
|
tcp6 0 0 ::1.8187 *.* LISTEN
|
2021-04-12 16:17:03 +00:00
|
|
|
tcp4 0 0 127.1.2.3.8188 *.* LISTEN
|
2021-04-12 16:06:57 +00:00
|
|
|
|
2022-11-04 13:41:36 +00:00
|
|
|
udp6 0 0 *.106 *.*
|
|
|
|
udp4 0 0 *.104 *.*
|
|
|
|
udp46 0 0 *.146 *.*
|
2020-02-05 22:16:58 +00:00
|
|
|
`
|
|
|
|
|
|
|
|
func TestParsePortsNetstat(t *testing.T) {
|
2023-05-24 16:52:45 +00:00
|
|
|
for _, loopBack := range [...]bool{false, true} {
|
|
|
|
t.Run(fmt.Sprintf("loopback_%v", loopBack), func(t *testing.T) {
|
|
|
|
want := List{
|
|
|
|
{"tcp", 23, "", 0},
|
|
|
|
{"tcp", 24, "", 0},
|
|
|
|
{"udp", 104, "", 0},
|
|
|
|
{"udp", 106, "", 0},
|
|
|
|
{"udp", 146, "", 0},
|
|
|
|
{"tcp", 8185, "", 0}, // but not 8186, 8187, 8188 on localhost, when loopback is false
|
|
|
|
}
|
|
|
|
if loopBack {
|
|
|
|
want = append(want,
|
|
|
|
Port{"tcp", 8186, "", 0},
|
|
|
|
Port{"tcp", 8187, "", 0},
|
|
|
|
Port{"tcp", 8188, "", 0},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
pl, err := appendParsePortsNetstat(nil, bufio.NewReader(strings.NewReader(netstatOutput)), loopBack)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
pl = sortAndDedup(pl)
|
|
|
|
jgot, _ := json.MarshalIndent(pl, "", "\t")
|
|
|
|
jwant, _ := json.MarshalIndent(want, "", "\t")
|
|
|
|
if len(pl) != len(want) {
|
|
|
|
t.Fatalf("Got:\n%s\n\nWant:\n%s\n", jgot, jwant)
|
|
|
|
}
|
|
|
|
for i := range pl {
|
|
|
|
if pl[i] != want[i] {
|
|
|
|
t.Errorf("row#%d\n got: %+v\n\nwant: %+v\n",
|
|
|
|
i, pl[i], want[i])
|
|
|
|
t.Fatalf("Got:\n%s\n\nWant:\n%s\n", jgot, jwant)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
}
|