(ctx context.Context, args []string)
| 933 | } |
| 934 | |
| 935 | func runVia(ctx context.Context, args []string) error { |
| 936 | switch len(args) { |
| 937 | default: |
| 938 | return errors.New("expect either <site-id> <v4-cidr> or <v6-route>") |
| 939 | case 1: |
| 940 | ipp, err := netip.ParsePrefix(args[0]) |
| 941 | if err != nil { |
| 942 | return err |
| 943 | } |
| 944 | if !ipp.Addr().Is6() { |
| 945 | return errors.New("with one argument, expect an IPv6 CIDR") |
| 946 | } |
| 947 | if !tsaddr.TailscaleViaRange().Contains(ipp.Addr()) { |
| 948 | return errors.New("not a via route") |
| 949 | } |
| 950 | if ipp.Bits() < 96 { |
| 951 | return errors.New("short length, want /96 or more") |
| 952 | } |
| 953 | v4 := tsaddr.UnmapVia(ipp.Addr()) |
| 954 | a := ipp.Addr().As16() |
| 955 | siteID := binary.BigEndian.Uint32(a[8:12]) |
| 956 | printf("site %v (0x%x), %v\n", siteID, siteID, netip.PrefixFrom(v4, ipp.Bits()-96)) |
| 957 | case 2: |
| 958 | siteID, err := strconv.ParseUint(args[0], 0, 32) |
| 959 | if err != nil { |
| 960 | return fmt.Errorf("invalid site-id %q; must be decimal or hex with 0x prefix", args[0]) |
| 961 | } |
| 962 | if siteID > 0xffff { |
| 963 | return fmt.Errorf("site-id values over 65535 are currently reserved") |
| 964 | } |
| 965 | ipp, err := netip.ParsePrefix(args[1]) |
| 966 | if err != nil { |
| 967 | return err |
| 968 | } |
| 969 | via, err := tsaddr.MapVia(uint32(siteID), ipp) |
| 970 | if err != nil { |
| 971 | return err |
| 972 | } |
| 973 | outln(via) |
| 974 | } |
| 975 | return nil |
| 976 | } |
| 977 | |
| 978 | var ts2021Args struct { |
| 979 | host string // "controlplane.tailscale.com" |
nothing calls this directly
no test coverage detected
searching dependent graphs…