Skip to content

(util) Auto-switching DNS based on Wi-Fi network

Published: at 08:00 PM

My utility program that detects which Wi-Fi network I’m connected to and updates my DNS settings accordingly


...

rules := map[string][]string{
"home-wifi": {"192.168.1.60"},
"work-wifi": {"1.1.1.1","9.9.9.9"},
}

func (dm *DNSManager) getSSID(ctx context.Context) (string, error) {
	switch runtime.GOOS {
	case "darwin":
		out, err := exec.CommandContext(ctx, "sh", "-c",
			"system_profiler SPAirPortDataType | awk '/Current Network Information:/ { getline; print substr($0, 13, (length($0) - 13)); exit }'").Output()
		if err != nil {
			return "", fmt.Errorf("failed to get current SSID: %w", err)
		}
		return strings.TrimSpace(string(out)), nil

	default:
		return "", fmt.Errorf("unsupported OS: %s", runtime.GOOS)
	}
}

func (dm *DNSManager) setDNS(ctx context.Context, servers []string) error {
	switch runtime.GOOS {
	case "darwin":
		var cmd *exec.Cmd

		if len(servers) == 0 {
			cmd = exec.CommandContext(ctx, "networksetup", "-setdnsservers", "Wi-Fi", "Empty")
		} else {
			args := append([]string{"-setdnsservers", "Wi-Fi"}, servers...)
			cmd = exec.CommandContext(ctx, "networksetup", args...)
		}

		if err := cmd.Run(); err != nil {
			return fmt.Errorf("failed to set DNS servers %v: %w", servers, err)
		}
		return nil

	default:
		return fmt.Errorf("unsupported OS: %s", runtime.GOOS)
	}
}

The code does three things:

It’s nothing fancy, but it saves me from manually opening System Preferences every time.