interfaces.go 22 KB

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