For reuse by derper, etc. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>main
parent
37e115834e
commit
433b917977
@ -0,0 +1,58 @@ |
||||
// 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 contains helpers for looking up system network interfaces.
|
||||
package interfaces |
||||
|
||||
import ( |
||||
"net" |
||||
"strings" |
||||
) |
||||
|
||||
// Tailscale returns the current machine's Tailscale interface, if any.
|
||||
// If none is found, all zero values are returned.
|
||||
// A non-nil error is only returned on a problem listing the system interfaces.
|
||||
func Tailscale() (net.IP, *net.Interface, error) { |
||||
ifs, err := net.Interfaces() |
||||
if err != nil { |
||||
return nil, nil, err |
||||
} |
||||
for _, iface := range ifs { |
||||
if !maybeTailscaleInterfaceName(iface.Name) { |
||||
continue |
||||
} |
||||
addrs, err := iface.Addrs() |
||||
if err != nil { |
||||
continue |
||||
} |
||||
for _, a := range addrs { |
||||
if ipnet, ok := a.(*net.IPNet); ok && IsTailscaleIP(ipnet.IP) { |
||||
return ipnet.IP, &iface, nil |
||||
} |
||||
} |
||||
} |
||||
return nil, nil, nil |
||||
} |
||||
|
||||
// maybeTailscaleInterfaceName reports whether s is an interface
|
||||
// name that might be used by Tailscale.
|
||||
func maybeTailscaleInterfaceName(s string) bool { |
||||
return strings.HasPrefix(s, "wg") || |
||||
strings.HasPrefix(s, "ts") || |
||||
strings.HasPrefix(s, "tailscale") |
||||
} |
||||
|
||||
// IsTailscaleIP reports whether ip is an IP in a range used by
|
||||
// Tailscale virtual network interfaces.
|
||||
func IsTailscaleIP(ip net.IP) bool { |
||||
return cgNAT.Contains(ip) |
||||
} |
||||
|
||||
var cgNAT = func() *net.IPNet { |
||||
_, ipNet, err := net.ParseCIDR("100.64.0.0/10") |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
return ipNet |
||||
}() |
||||
@ -0,0 +1,31 @@ |
||||
// 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 ( |
||||
"net" |
||||
"testing" |
||||
) |
||||
|
||||
func TestIsTailscaleIP(t *testing.T) { |
||||
tests := []struct { |
||||
ip string |
||||
want bool |
||||
}{ |
||||
{"100.81.251.94", true}, |
||||
{"8.8.8.8", false}, |
||||
} |
||||
for _, tt := range tests { |
||||
ip := net.ParseIP(tt.ip) |
||||
if ip == nil { |
||||
t.Fatalf("failed to parse IP %q", tt.ip) |
||||
} |
||||
got := IsTailscaleIP(ip) |
||||
if got != tt.want { |
||||
t.Errorf("F(%q) = %v; want %v", tt.ip, got, tt.want) |
||||
} |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue