net/interfaces: add interfaces.State.String method

This commit is contained in:
Brad Fitzpatrick 2020-10-02 12:07:00 -07:00
parent 9784cae23b
commit ed5d5f920f
2 changed files with 72 additions and 0 deletions

View File

@ -10,6 +10,7 @@ import (
"net" "net"
"net/http" "net/http"
"reflect" "reflect"
"sort"
"strings" "strings"
"inet.af/netaddr" "inet.af/netaddr"
@ -182,6 +183,61 @@ type State struct {
PAC string PAC string
} }
func (s *State) String() string {
var sb strings.Builder
fmt.Fprintf(&sb, "interfaces.State{defaultRoute=%v ifs={", s.DefaultRouteInterface)
ifs := make([]string, 0, len(s.InterfaceUp))
for k := range s.InterfaceUp {
if allLoopbackIPs(s.InterfaceIPs[k]) {
continue
}
ifs = append(ifs, k)
}
sort.Slice(ifs, func(i, j int) bool {
upi, upj := s.InterfaceUp[ifs[i]], s.InterfaceUp[ifs[j]]
if upi != upj {
// Up sorts before down.
return upi
}
return ifs[i] < ifs[j]
})
for i, ifName := range ifs {
if i > 0 {
sb.WriteString(" ")
}
if s.InterfaceUp[ifName] {
fmt.Fprintf(&sb, "%s:[", ifName)
needSpace := false
for _, ip := range s.InterfaceIPs[ifName] {
if ip.IsLinkLocalUnicast() {
continue
}
if needSpace {
sb.WriteString(" ")
}
fmt.Fprintf(&sb, "%s", ip)
needSpace = true
}
sb.WriteString("]")
} else {
fmt.Fprintf(&sb, "%s:down", ifName)
}
}
sb.WriteString("}")
if s.IsExpensive {
sb.WriteString(" expensive")
}
if s.HTTPProxy != "" {
fmt.Fprintf(&sb, " httpproxy=%s", s.HTTPProxy)
}
if s.PAC != "" {
fmt.Fprintf(&sb, " pac=%s", s.PAC)
}
fmt.Fprintf(&sb, " v4=%v v6global=%v}", s.HaveV4, s.HaveV6Global)
return sb.String()
}
func (s *State) Equal(s2 *State) bool { func (s *State) Equal(s2 *State) bool {
return reflect.DeepEqual(s, s2) return reflect.DeepEqual(s, s2)
} }
@ -321,3 +377,15 @@ var (
linkLocalIPv4 = mustCIDR("169.254.0.0/16") linkLocalIPv4 = mustCIDR("169.254.0.0/16")
v6Global1 = mustCIDR("2000::/3") v6Global1 = mustCIDR("2000::/3")
) )
func allLoopbackIPs(ips []netaddr.IP) bool {
if len(ips) == 0 {
return false
}
for _, ip := range ips {
if !ip.IsLoopback() {
return false
}
}
return true
}

View File

@ -35,6 +35,7 @@ func TestGetState(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
t.Logf("Got: %#v", st) t.Logf("Got: %#v", st)
t.Logf("As string: %s", st)
st2, err := GetState() st2, err := GetState()
if err != nil { if err != nil {
@ -46,6 +47,9 @@ func TestGetState(t *testing.T) {
// the two GetState calls. // the two GetState calls.
t.Fatal("two States back-to-back were not equal") t.Fatal("two States back-to-back were not equal")
} }
st.RemoveTailscaleInterfaces()
t.Logf("As string without Tailscale:\n\t%s", st)
} }
func TestLikelyHomeRouterIP(t *testing.T) { func TestLikelyHomeRouterIP(t *testing.T) {