code.dwrz.net

Go monorepo.
Log | Files | Refs

digip.go (1654B)


      1 package digip
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 	"net"
      7 	"os/exec"
      8 	"strings"
      9 )
     10 
     11 type Version string
     12 
     13 const (
     14 	V4 = "-4"
     15 	V6 = "-6"
     16 )
     17 
     18 type Record string
     19 
     20 const (
     21 	A    = "A"
     22 	AAAA = "AAAA"
     23 )
     24 
     25 // dig -4 TXT +short o-o.myaddr.l.google.com @ns1.google.com
     26 // dig -6 TXT +short o-o.myaddr.l.google.com @ns1.google.com
     27 func Google(ctx context.Context, v Version) (net.IP, error) {
     28 	cmd := exec.CommandContext(
     29 		ctx,
     30 		"dig",
     31 		"TXT",
     32 		"+short",
     33 		string(v),
     34 		"o-o.myaddr.l.google.com",
     35 		"@ns1.google.com",
     36 	)
     37 	output, err := cmd.CombinedOutput()
     38 	if err != nil {
     39 		return nil, fmt.Errorf("dig failed: %v", err)
     40 	}
     41 	if string(output) == "" {
     42 		return nil, fmt.Errorf("dig failed: no output")
     43 	}
     44 	if len(output) < 2 {
     45 		return nil, fmt.Errorf(
     46 			"dig failed: unexpected output: %s", string(output),
     47 		)
     48 	}
     49 
     50 	// Google returns the IP with quotes.
     51 	// We need to trim the quotes.
     52 	trimmed := strings.TrimSpace(string(output))
     53 	ip := net.ParseIP(trimmed[1 : len(trimmed)-1])
     54 
     55 	return ip, nil
     56 }
     57 
     58 // dig A +short myip.opendns.com @resolver1.opendns.com
     59 // dig AAAA +short myip.opendns.com @resolver1.opendns.com
     60 func OpenDNS(ctx context.Context, r Record) (net.IP, error) {
     61 	cmd := exec.CommandContext(
     62 		ctx,
     63 		"dig",
     64 		"+short",
     65 		string(r),
     66 		"myip.opendns.com",
     67 		"@resolver1.opendns.com",
     68 	)
     69 	output, err := cmd.CombinedOutput()
     70 	if err != nil {
     71 		return nil, fmt.Errorf("dig failed: %v", err)
     72 	}
     73 	if string(output) == "" {
     74 		return nil, fmt.Errorf("dig failed: no output")
     75 	}
     76 	if len(output) < 2 {
     77 		return nil, fmt.Errorf(
     78 			"dig failed: unexpected output: %s", string(output),
     79 		)
     80 	}
     81 
     82 	ip := net.ParseIP(strings.TrimSpace(string(output)))
     83 
     84 	return ip, nil
     85 }