interfaces.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package interfaces contains helpers for looking up system network interfaces.
  4. package interfaces
  5. import (
  6. "bytes"
  7. "fmt"
  8. "net"
  9. "net/http"
  10. "net/netip"
  11. "runtime"
  12. "sort"
  13. "strings"
  14. "tailscale.com/hostinfo"
  15. "tailscale.com/net/netaddr"
  16. "tailscale.com/net/tsaddr"
  17. "tailscale.com/net/tshttpproxy"
  18. )
  19. // LoginEndpointForProxyDetermination is the URL used for testing
  20. // which HTTP proxy the system should use.
  21. var LoginEndpointForProxyDetermination = "https://controlplane.tailscale.com/"
  22. // Tailscale returns the current machine's Tailscale interface, if any.
  23. // If none is found, all zero values are returned.
  24. // A non-nil error is only returned on a problem listing the system interfaces.
  25. func Tailscale() ([]netip.Addr, *net.Interface, error) {
  26. ifs, err := netInterfaces()
  27. if err != nil {
  28. return nil, nil, err
  29. }
  30. for _, iface := range ifs {
  31. if !maybeTailscaleInterfaceName(iface.Name) {
  32. continue
  33. }
  34. addrs, err := iface.Addrs()
  35. if err != nil {
  36. continue
  37. }
  38. var tsIPs []netip.Addr
  39. for _, a := range addrs {
  40. if ipnet, ok := a.(*net.IPNet); ok {
  41. nip, ok := netip.AddrFromSlice(ipnet.IP)
  42. nip = nip.Unmap()
  43. if ok && tsaddr.IsTailscaleIP(nip) {
  44. tsIPs = append(tsIPs, nip)
  45. }
  46. }
  47. }
  48. if len(tsIPs) > 0 {
  49. return tsIPs, iface.Interface, nil
  50. }
  51. }
  52. return nil, nil, nil
  53. }
  54. // maybeTailscaleInterfaceName reports whether s is an interface
  55. // name that might be used by Tailscale.
  56. func maybeTailscaleInterfaceName(s string) bool {
  57. return s == "Tailscale" ||
  58. strings.HasPrefix(s, "wg") ||
  59. strings.HasPrefix(s, "ts") ||
  60. strings.HasPrefix(s, "tailscale") ||
  61. strings.HasPrefix(s, "utun")
  62. }
  63. func isUp(nif *net.Interface) bool { return nif.Flags&net.FlagUp != 0 }
  64. func isLoopback(nif *net.Interface) bool { return nif.Flags&net.FlagLoopback != 0 }
  65. func isProblematicInterface(nif *net.Interface) bool {
  66. name := nif.Name
  67. // Don't try to send disco/etc packets over zerotier; they effectively
  68. // DoS each other by doing traffic amplification, both of them
  69. // preferring/trying to use each other for transport. See:
  70. // https://github.com/tailscale/tailscale/issues/1208
  71. if strings.HasPrefix(name, "zt") || (runtime.GOOS == "windows" && strings.Contains(name, "ZeroTier")) {
  72. return true
  73. }
  74. return false
  75. }
  76. // LocalAddresses returns the machine's IP addresses, separated by
  77. // whether they're loopback addresses. If there are no regular addresses
  78. // it will return any IPv4 linklocal or IPv6 unique local addresses because we
  79. // know of environments where these are used with NAT to provide connectivity.
  80. func LocalAddresses() (regular, loopback []netip.Addr, err error) {
  81. // TODO(crawshaw): don't serve interface addresses that we are routing
  82. ifaces, err := netInterfaces()
  83. if err != nil {
  84. return nil, nil, err
  85. }
  86. var regular4, regular6, linklocal4, ula6 []netip.Addr
  87. for _, iface := range ifaces {
  88. stdIf := iface.Interface
  89. if !isUp(stdIf) || isProblematicInterface(stdIf) {
  90. // Skip down interfaces and ones that are
  91. // problematic that we don't want to try to
  92. // send Tailscale traffic over.
  93. continue
  94. }
  95. ifcIsLoopback := isLoopback(stdIf)
  96. addrs, err := iface.Addrs()
  97. if err != nil {
  98. return nil, nil, err
  99. }
  100. for _, a := range addrs {
  101. switch v := a.(type) {
  102. case *net.IPNet:
  103. ip, ok := netip.AddrFromSlice(v.IP)
  104. if !ok {
  105. continue
  106. }
  107. ip = ip.Unmap()
  108. // TODO(apenwarr): don't special case cgNAT.
  109. // In the general wireguard case, it might
  110. // very well be something we can route to
  111. // directly, because both nodes are
  112. // behind the same CGNAT router.
  113. if tsaddr.IsTailscaleIP(ip) {
  114. continue
  115. }
  116. if ip.IsLoopback() || ifcIsLoopback {
  117. loopback = append(loopback, ip)
  118. } else if ip.IsLinkLocalUnicast() {
  119. if ip.Is4() {
  120. linklocal4 = append(linklocal4, ip)
  121. }
  122. // We know of no cases where the IPv6 fe80:: addresses
  123. // are used to provide WAN connectivity. It is also very
  124. // common for users to have no IPv6 WAN connectivity,
  125. // but their OS supports IPv6 so they have an fe80::
  126. // address. We don't want to report all of those
  127. // IPv6 LL to Control.
  128. } else if ip.Is6() && ip.IsPrivate() {
  129. // Google Cloud Run uses NAT with IPv6 Unique
  130. // Local Addresses to provide IPv6 connectivity.
  131. ula6 = append(ula6, ip)
  132. } else {
  133. if ip.Is4() {
  134. regular4 = append(regular4, ip)
  135. } else {
  136. regular6 = append(regular6, ip)
  137. }
  138. }
  139. }
  140. }
  141. }
  142. if len(regular4) == 0 && len(regular6) == 0 {
  143. // if we have no usable IP addresses then be willing to accept
  144. // addresses we otherwise wouldn't, like:
  145. // + 169.254.x.x (AWS Lambda and Azure App Services use NAT with these)
  146. // + IPv6 ULA (Google Cloud Run uses these with address translation)
  147. regular4 = linklocal4
  148. regular6 = ula6
  149. }
  150. regular = append(regular4, regular6...)
  151. sortIPs(regular)
  152. sortIPs(loopback)
  153. return regular, loopback, nil
  154. }
  155. func sortIPs(s []netip.Addr) {
  156. sort.Slice(s, func(i, j int) bool { return s[i].Less(s[j]) })
  157. }
  158. // Interface is a wrapper around Go's net.Interface with some extra methods.
  159. type Interface struct {
  160. *net.Interface
  161. AltAddrs []net.Addr // if non-nil, returned by Addrs
  162. Desc string // extra description (used on Windows)
  163. }
  164. func (i Interface) IsLoopback() bool { return isLoopback(i.Interface) }
  165. func (i Interface) IsUp() bool { return isUp(i.Interface) }
  166. func (i Interface) Addrs() ([]net.Addr, error) {
  167. if i.AltAddrs != nil {
  168. return i.AltAddrs, nil
  169. }
  170. return i.Interface.Addrs()
  171. }
  172. // ForeachInterfaceAddress is a wrapper for GetList, then
  173. // List.ForeachInterfaceAddress.
  174. func ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
  175. ifaces, err := GetList()
  176. if err != nil {
  177. return err
  178. }
  179. return ifaces.ForeachInterfaceAddress(fn)
  180. }
  181. // ForeachInterfaceAddress calls fn for each interface in ifaces, with
  182. // all its addresses. The IPPrefix's IP is the IP address assigned to
  183. // the interface, and Bits are the subnet mask.
  184. func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
  185. for _, iface := range ifaces {
  186. addrs, err := iface.Addrs()
  187. if err != nil {
  188. return err
  189. }
  190. for _, a := range addrs {
  191. switch v := a.(type) {
  192. case *net.IPNet:
  193. if pfx, ok := netaddr.FromStdIPNet(v); ok {
  194. fn(iface, pfx)
  195. }
  196. }
  197. }
  198. }
  199. return nil
  200. }
  201. // ForeachInterface is a wrapper for GetList, then
  202. // List.ForeachInterface.
  203. func ForeachInterface(fn func(Interface, []netip.Prefix)) error {
  204. ifaces, err := GetList()
  205. if err != nil {
  206. return err
  207. }
  208. return ifaces.ForeachInterface(fn)
  209. }
  210. // ForeachInterface calls fn for each interface in ifaces, with
  211. // all its addresses. The IPPrefix's IP is the IP address assigned to
  212. // the interface, and Bits are the subnet mask.
  213. func (ifaces List) ForeachInterface(fn func(Interface, []netip.Prefix)) error {
  214. for _, iface := range ifaces {
  215. addrs, err := iface.Addrs()
  216. if err != nil {
  217. return err
  218. }
  219. var pfxs []netip.Prefix
  220. for _, a := range addrs {
  221. switch v := a.(type) {
  222. case *net.IPNet:
  223. if pfx, ok := netaddr.FromStdIPNet(v); ok {
  224. pfxs = append(pfxs, pfx)
  225. }
  226. }
  227. }
  228. sort.Slice(pfxs, func(i, j int) bool {
  229. return pfxs[i].Addr().Less(pfxs[j].Addr())
  230. })
  231. fn(iface, pfxs)
  232. }
  233. return nil
  234. }
  235. // State is intended to store the state of the machine's network interfaces,
  236. // routing table, and other network configuration.
  237. // For now it's pretty basic.
  238. type State struct {
  239. // InterfaceIPs maps from an interface name to the IP addresses
  240. // configured on that interface. Each address is represented as an
  241. // IPPrefix, where the IP is the interface IP address and Bits is
  242. // the subnet mask.
  243. InterfaceIPs map[string][]netip.Prefix
  244. Interface map[string]Interface
  245. // HaveV6 is whether this machine has an IPv6 Global or Unique Local Address
  246. // which might provide connectivity on a non-Tailscale interface that's up.
  247. HaveV6 bool
  248. // HaveV4 is whether the machine has some non-localhost,
  249. // non-link-local IPv4 address on a non-Tailscale interface that's up.
  250. HaveV4 bool
  251. // IsExpensive is whether the current network interface is
  252. // considered "expensive", which currently means LTE/etc
  253. // instead of Wifi. This field is not populated by GetState.
  254. IsExpensive bool
  255. // DefaultRouteInterface is the interface name for the
  256. // machine's default route.
  257. //
  258. // It is not yet populated on all OSes.
  259. //
  260. // When non-empty, its value is the map key into Interface and
  261. // InterfaceIPs.
  262. DefaultRouteInterface string
  263. // HTTPProxy is the HTTP proxy to use, if any.
  264. HTTPProxy string
  265. // PAC is the URL to the Proxy Autoconfig URL, if applicable.
  266. PAC string
  267. }
  268. func (s *State) String() string {
  269. var sb strings.Builder
  270. fmt.Fprintf(&sb, "interfaces.State{defaultRoute=%v ", s.DefaultRouteInterface)
  271. if s.DefaultRouteInterface != "" {
  272. if iface, ok := s.Interface[s.DefaultRouteInterface]; ok && iface.Desc != "" {
  273. fmt.Fprintf(&sb, "(%s) ", iface.Desc)
  274. }
  275. }
  276. sb.WriteString("ifs={")
  277. ifs := make([]string, 0, len(s.Interface))
  278. for k := range s.Interface {
  279. if anyInterestingIP(s.InterfaceIPs[k]) {
  280. ifs = append(ifs, k)
  281. }
  282. }
  283. sort.Slice(ifs, func(i, j int) bool {
  284. upi, upj := s.Interface[ifs[i]].IsUp(), s.Interface[ifs[j]].IsUp()
  285. if upi != upj {
  286. // Up sorts before down.
  287. return upi
  288. }
  289. return ifs[i] < ifs[j]
  290. })
  291. for i, ifName := range ifs {
  292. if i > 0 {
  293. sb.WriteString(" ")
  294. }
  295. if s.Interface[ifName].IsUp() {
  296. fmt.Fprintf(&sb, "%s:[", ifName)
  297. needSpace := false
  298. for _, pfx := range s.InterfaceIPs[ifName] {
  299. if !isInterestingIP(pfx.Addr()) {
  300. continue
  301. }
  302. if needSpace {
  303. sb.WriteString(" ")
  304. }
  305. fmt.Fprintf(&sb, "%s", pfx)
  306. needSpace = true
  307. }
  308. sb.WriteString("]")
  309. } else {
  310. fmt.Fprintf(&sb, "%s:down", ifName)
  311. }
  312. }
  313. sb.WriteString("}")
  314. if s.IsExpensive {
  315. sb.WriteString(" expensive")
  316. }
  317. if s.HTTPProxy != "" {
  318. fmt.Fprintf(&sb, " httpproxy=%s", s.HTTPProxy)
  319. }
  320. if s.PAC != "" {
  321. fmt.Fprintf(&sb, " pac=%s", s.PAC)
  322. }
  323. fmt.Fprintf(&sb, " v4=%v v6=%v}", s.HaveV4, s.HaveV6)
  324. return sb.String()
  325. }
  326. // An InterfaceFilter indicates whether EqualFiltered should use i when deciding whether two States are equal.
  327. // ips are all the IPPrefixes associated with i.
  328. type InterfaceFilter func(i Interface, ips []netip.Prefix) bool
  329. // An IPFilter indicates whether EqualFiltered should use ip when deciding whether two States are equal.
  330. // ip is an ip address associated with some interface under consideration.
  331. type IPFilter func(ip netip.Addr) bool
  332. // EqualFiltered reports whether s and s2 are equal,
  333. // considering only interfaces in s for which filter returns true,
  334. // and considering only IPs for those interfaces for which filterIP returns true.
  335. func (s *State) EqualFiltered(s2 *State, useInterface InterfaceFilter, useIP IPFilter) bool {
  336. if s == nil && s2 == nil {
  337. return true
  338. }
  339. if s == nil || s2 == nil {
  340. return false
  341. }
  342. if s.HaveV6 != s2.HaveV6 ||
  343. s.HaveV4 != s2.HaveV4 ||
  344. s.IsExpensive != s2.IsExpensive ||
  345. s.DefaultRouteInterface != s2.DefaultRouteInterface ||
  346. s.HTTPProxy != s2.HTTPProxy ||
  347. s.PAC != s2.PAC {
  348. return false
  349. }
  350. for iname, i := range s.Interface {
  351. ips := s.InterfaceIPs[iname]
  352. if !useInterface(i, ips) {
  353. continue
  354. }
  355. i2, ok := s2.Interface[iname]
  356. if !ok {
  357. return false
  358. }
  359. ips2, ok := s2.InterfaceIPs[iname]
  360. if !ok {
  361. return false
  362. }
  363. if !interfacesEqual(i, i2) || !prefixesEqualFiltered(ips, ips2, useIP) {
  364. return false
  365. }
  366. }
  367. return true
  368. }
  369. // HasIP reports whether any interface has the provided IP address.
  370. func (s *State) HasIP(ip netip.Addr) bool {
  371. if s == nil {
  372. return false
  373. }
  374. want := netip.PrefixFrom(ip, ip.BitLen())
  375. for _, pv := range s.InterfaceIPs {
  376. for _, p := range pv {
  377. if p == want {
  378. return true
  379. }
  380. }
  381. }
  382. return false
  383. }
  384. func interfacesEqual(a, b Interface) bool {
  385. return a.Index == b.Index &&
  386. a.MTU == b.MTU &&
  387. a.Name == b.Name &&
  388. a.Flags == b.Flags &&
  389. bytes.Equal([]byte(a.HardwareAddr), []byte(b.HardwareAddr))
  390. }
  391. func filteredIPPs(ipps []netip.Prefix, useIP IPFilter) []netip.Prefix {
  392. // TODO: rewrite prefixesEqualFiltered to avoid making copies
  393. x := make([]netip.Prefix, 0, len(ipps))
  394. for _, ipp := range ipps {
  395. if useIP(ipp.Addr()) {
  396. x = append(x, ipp)
  397. }
  398. }
  399. return x
  400. }
  401. func prefixesEqualFiltered(a, b []netip.Prefix, useIP IPFilter) bool {
  402. return prefixesEqual(filteredIPPs(a, useIP), filteredIPPs(b, useIP))
  403. }
  404. func prefixesEqual(a, b []netip.Prefix) bool {
  405. if len(a) != len(b) {
  406. return false
  407. }
  408. for i, v := range a {
  409. if b[i] != v {
  410. return false
  411. }
  412. }
  413. return true
  414. }
  415. // UseInterestingInterfaces is an InterfaceFilter that reports whether i is an interesting interface.
  416. // An interesting interface if it is (a) not owned by Tailscale and (b) routes interesting IP addresses.
  417. // See UseInterestingIPs for the definition of an interesting IP address.
  418. func UseInterestingInterfaces(i Interface, ips []netip.Prefix) bool {
  419. return !isTailscaleInterface(i.Name, ips) && anyInterestingIP(ips)
  420. }
  421. // UseInterestingIPs is an IPFilter that reports whether ip is an interesting IP address.
  422. // An IP address is interesting if it is neither a loopback nor a link local unicast IP address.
  423. func UseInterestingIPs(ip netip.Addr) bool {
  424. return isInterestingIP(ip)
  425. }
  426. // UseAllInterfaces is an InterfaceFilter that includes all interfaces.
  427. func UseAllInterfaces(i Interface, ips []netip.Prefix) bool { return true }
  428. // UseAllIPs is an IPFilter that includes all IPs.
  429. func UseAllIPs(ips netip.Addr) bool { return true }
  430. func (s *State) HasPAC() bool { return s != nil && s.PAC != "" }
  431. // AnyInterfaceUp reports whether any interface seems like it has Internet access.
  432. func (s *State) AnyInterfaceUp() bool {
  433. if runtime.GOOS == "js" {
  434. return true
  435. }
  436. return s != nil && (s.HaveV4 || s.HaveV6)
  437. }
  438. func hasTailscaleIP(pfxs []netip.Prefix) bool {
  439. for _, pfx := range pfxs {
  440. if tsaddr.IsTailscaleIP(pfx.Addr()) {
  441. return true
  442. }
  443. }
  444. return false
  445. }
  446. func isTailscaleInterface(name string, ips []netip.Prefix) bool {
  447. if runtime.GOOS == "darwin" && strings.HasPrefix(name, "utun") && hasTailscaleIP(ips) {
  448. // On macOS in the sandboxed app (at least as of
  449. // 2021-02-25), we often see two utun devices
  450. // (e.g. utun4 and utun7) with the same IPv4 and IPv6
  451. // addresses. Just remove all utun devices with
  452. // Tailscale IPs until we know what's happening with
  453. // macOS NetworkExtensions and utun devices.
  454. return true
  455. }
  456. return name == "Tailscale" || // as it is on Windows
  457. strings.HasPrefix(name, "tailscale") // TODO: use --tun flag value, etc; see TODO in method doc
  458. }
  459. // getPAC, if non-nil, returns the current PAC file URL.
  460. var getPAC func() string
  461. // GetState returns the state of all the current machine's network interfaces.
  462. //
  463. // It does not set the returned State.IsExpensive. The caller can populate that.
  464. func GetState() (*State, error) {
  465. s := &State{
  466. InterfaceIPs: make(map[string][]netip.Prefix),
  467. Interface: make(map[string]Interface),
  468. }
  469. if err := ForeachInterface(func(ni Interface, pfxs []netip.Prefix) {
  470. ifUp := ni.IsUp()
  471. s.Interface[ni.Name] = ni
  472. s.InterfaceIPs[ni.Name] = append(s.InterfaceIPs[ni.Name], pfxs...)
  473. if !ifUp || isTailscaleInterface(ni.Name, pfxs) {
  474. return
  475. }
  476. for _, pfx := range pfxs {
  477. if pfx.Addr().IsLoopback() {
  478. continue
  479. }
  480. s.HaveV6 = s.HaveV6 || isUsableV6(pfx.Addr())
  481. s.HaveV4 = s.HaveV4 || isUsableV4(pfx.Addr())
  482. }
  483. }); err != nil {
  484. return nil, err
  485. }
  486. dr, _ := DefaultRoute()
  487. s.DefaultRouteInterface = dr.InterfaceName
  488. // Populate description (for Windows, primarily) if present.
  489. if desc := dr.InterfaceDesc; desc != "" {
  490. if iface, ok := s.Interface[dr.InterfaceName]; ok {
  491. iface.Desc = desc
  492. s.Interface[dr.InterfaceName] = iface
  493. }
  494. }
  495. if s.AnyInterfaceUp() {
  496. req, err := http.NewRequest("GET", LoginEndpointForProxyDetermination, nil)
  497. if err != nil {
  498. return nil, err
  499. }
  500. if u, err := tshttpproxy.ProxyFromEnvironment(req); err == nil && u != nil {
  501. s.HTTPProxy = u.String()
  502. }
  503. if getPAC != nil {
  504. s.PAC = getPAC()
  505. }
  506. }
  507. return s, nil
  508. }
  509. // HTTPOfListener returns the HTTP address to ln.
  510. // If the listener is listening on the unspecified address, it
  511. // it tries to find a reasonable interface address on the machine to use.
  512. func HTTPOfListener(ln net.Listener) string {
  513. ta, ok := ln.Addr().(*net.TCPAddr)
  514. if !ok || !ta.IP.IsUnspecified() {
  515. return fmt.Sprintf("http://%v/", ln.Addr())
  516. }
  517. var goodIP string
  518. var privateIP string
  519. ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
  520. ip := pfx.Addr()
  521. if ip.IsPrivate() {
  522. if privateIP == "" {
  523. privateIP = ip.String()
  524. }
  525. return
  526. }
  527. goodIP = ip.String()
  528. })
  529. if privateIP != "" {
  530. goodIP = privateIP
  531. }
  532. if goodIP != "" {
  533. return fmt.Sprintf("http://%v/", net.JoinHostPort(goodIP, fmt.Sprint(ta.Port)))
  534. }
  535. return fmt.Sprintf("http://localhost:%v/", fmt.Sprint(ta.Port))
  536. }
  537. var likelyHomeRouterIP func() (netip.Addr, bool)
  538. // LikelyHomeRouterIP returns the likely IP of the residential router,
  539. // which will always be an IPv4 private address, if found.
  540. // In addition, it returns the IP address of the current machine on
  541. // the LAN using that gateway.
  542. // This is used as the destination for UPnP, NAT-PMP, PCP, etc queries.
  543. func LikelyHomeRouterIP() (gateway, myIP netip.Addr, ok bool) {
  544. if likelyHomeRouterIP != nil {
  545. gateway, ok = likelyHomeRouterIP()
  546. if !ok {
  547. return
  548. }
  549. }
  550. if !ok {
  551. return
  552. }
  553. ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
  554. if !i.IsUp() {
  555. // Skip interfaces that aren't up.
  556. return
  557. } else if myIP.IsValid() {
  558. // We already have a valid self IP; skip this one.
  559. return
  560. }
  561. ip := pfx.Addr()
  562. if !ip.IsValid() || !ip.Is4() {
  563. // Skip IPs that aren't valid or aren't IPv4, since we
  564. // always return an IPv4 address.
  565. return
  566. }
  567. if gateway.IsPrivate() && ip.IsPrivate() {
  568. myIP = ip
  569. ok = true
  570. return
  571. }
  572. })
  573. return gateway, myIP, myIP.IsValid()
  574. }
  575. // isUsableV4 reports whether ip is a usable IPv4 address which could
  576. // conceivably be used to get Internet connectivity. Globally routable and
  577. // private IPv4 addresses are always Usable, and link local 169.254.x.x
  578. // addresses are in some environments.
  579. func isUsableV4(ip netip.Addr) bool {
  580. if !ip.Is4() || ip.IsLoopback() {
  581. return false
  582. }
  583. if ip.IsLinkLocalUnicast() {
  584. switch hostinfo.GetEnvType() {
  585. case hostinfo.AWSLambda:
  586. return true
  587. case hostinfo.AzureAppService:
  588. return true
  589. default:
  590. return false
  591. }
  592. }
  593. return true
  594. }
  595. // isUsableV6 reports whether ip is a usable IPv6 address which could
  596. // conceivably be used to get Internet connectivity. Globally routable
  597. // IPv6 addresses are always Usable, and Unique Local Addresses
  598. // (fc00::/7) are in some environments used with address translation.
  599. func isUsableV6(ip netip.Addr) bool {
  600. return v6Global1.Contains(ip) ||
  601. (ip.Is6() && ip.IsPrivate() && !tsaddr.TailscaleULARange().Contains(ip))
  602. }
  603. var (
  604. v6Global1 = netip.MustParsePrefix("2000::/3")
  605. )
  606. // anyInterestingIP reports whether pfxs contains any IP that matches
  607. // isInterestingIP.
  608. func anyInterestingIP(pfxs []netip.Prefix) bool {
  609. for _, pfx := range pfxs {
  610. if isInterestingIP(pfx.Addr()) {
  611. return true
  612. }
  613. }
  614. return false
  615. }
  616. // isInterestingIP reports whether ip is an interesting IP that we
  617. // should log in interfaces.State logging. We don't need to show
  618. // localhost or link-local addresses.
  619. func isInterestingIP(ip netip.Addr) bool {
  620. return !ip.IsLoopback() && !ip.IsLinkLocalUnicast()
  621. }
  622. var altNetInterfaces func() ([]Interface, error)
  623. // RegisterInterfaceGetter sets the function that's used to query
  624. // the system network interfaces.
  625. func RegisterInterfaceGetter(getInterfaces func() ([]Interface, error)) {
  626. altNetInterfaces = getInterfaces
  627. }
  628. // List is a list of interfaces on the machine.
  629. type List []Interface
  630. // GetList returns the list of interfaces on the machine.
  631. func GetList() (List, error) {
  632. return netInterfaces()
  633. }
  634. // netInterfaces is a wrapper around the standard library's net.Interfaces
  635. // that returns a []*Interface instead of a []net.Interface.
  636. // It exists because Android SDK 30 no longer permits Go's net.Interfaces
  637. // to work (Issue 2293); this wrapper lets us the Android app register
  638. // an alternate implementation.
  639. func netInterfaces() ([]Interface, error) {
  640. if altNetInterfaces != nil {
  641. return altNetInterfaces()
  642. }
  643. ifs, err := net.Interfaces()
  644. if err != nil {
  645. return nil, err
  646. }
  647. ret := make([]Interface, len(ifs))
  648. for i := range ifs {
  649. ret[i].Interface = &ifs[i]
  650. }
  651. return ret, nil
  652. }
  653. // DefaultRouteDetails are the details about a default route returned
  654. // by DefaultRoute.
  655. type DefaultRouteDetails struct {
  656. // InterfaceName is the interface name. It must always be populated.
  657. // It's like "eth0" (Linux), "Ethernet 2" (Windows), "en0" (macOS).
  658. InterfaceName string
  659. // InterfaceDesc is populated on Windows at least. It's a
  660. // longer description, like "Red Hat VirtIO Ethernet Adapter".
  661. InterfaceDesc string
  662. // InterfaceIndex is like net.Interface.Index.
  663. // Zero means not populated.
  664. InterfaceIndex int
  665. // TODO(bradfitz): break this out into v4-vs-v6 once that need arises.
  666. }
  667. // DefaultRouteInterface is like DefaultRoute but only returns the
  668. // interface name.
  669. func DefaultRouteInterface() (string, error) {
  670. dr, err := DefaultRoute()
  671. if err != nil {
  672. return "", err
  673. }
  674. return dr.InterfaceName, nil
  675. }
  676. // DefaultRoute returns details of the network interface that owns
  677. // the default route, not including any tailscale interfaces.
  678. func DefaultRoute() (DefaultRouteDetails, error) {
  679. return defaultRoute()
  680. }
  681. // HasCGNATInterface reports whether there are any non-Tailscale interfaces that
  682. // use a CGNAT IP range.
  683. func HasCGNATInterface() (bool, error) {
  684. hasCGNATInterface := false
  685. cgnatRange := tsaddr.CGNATRange()
  686. err := ForeachInterface(func(i Interface, pfxs []netip.Prefix) {
  687. if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) {
  688. return
  689. }
  690. for _, pfx := range pfxs {
  691. if cgnatRange.Overlaps(pfx) {
  692. hasCGNATInterface = true
  693. break
  694. }
  695. }
  696. })
  697. if err != nil {
  698. return false, err
  699. }
  700. return hasCGNATInterface, nil
  701. }
  702. var interfaceDebugExtras func(ifIndex int) (string, error)
  703. // InterfaceDebugExtras returns extra debugging information about an interface
  704. // if any (an empty string will be returned if there are no additional details).
  705. // Formatting is platform-dependent and should not be parsed.
  706. func InterfaceDebugExtras(ifIndex int) (string, error) {
  707. if interfaceDebugExtras != nil {
  708. return interfaceDebugExtras(ifIndex)
  709. }
  710. return "", nil
  711. }