diff --git a/main.go b/main.go index 8de3e1f..4d11714 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,21 @@ +// A small Go web‑server that converts an IPv4 address into an IPv6 address +// inside a user‑defined /96 ULA prefix and outputs Windows 11‑ready fields. +// +// Environment variables (all optional): +// +// ULA_PREFIX – /96 prefix to embed into, default "fdcb:7de3:a12a:0::" +// FORM_DEFAULT_IP - legt das Form Placeholder IP Feld fest (default: 172.16.0.0) +// DNS1 – preferred DNS IPv6 address (default: ) +// DNS2 – alternate DNS IPv6 address (default: ) +// +// Build & run: +// +// export ULA_PREFIX="fde5:1234:abcd:0::" +// export DNS1="fde5:1234:abcd:1::53" # optional +// export DNS2="fde5:1234:abcd:1::54" # optional +// go run main.go +// +// Open http://localhost:8080 in a browser. package main import ( @@ -11,29 +29,36 @@ import ( ) const ( - listenAddr = ":8080" // TCP port for the web UI - defaultPrefix = "fdcb:7de3:a12a:0::" // fallback when ULA_PREFIX is unset + listenAddr = ":8080" + defaultPrefix = "fd09:cafe:affe:4010::" // fallback /96 + prefixLen = 96 // fixed /96 mapping defaultIP = "172.16.0.0" ) var ( - ulaPrefix string // effective /96 prefix (always ending in "::") - pageTemplate *template.Template // populated in init() + ulaPrefix string // effective /96 prefix (always ends with ::) + dns1 string // preferred DNS + dns2 string // alternate DNS pageIP string + pageTemplate *template.Template // compiled HTML template ) -// viewData feeds data into the HTML template. +// viewData is passed into the template. type viewData struct { - IPv4 string - IPv6 string - Error string + IPv4 string + IPv6 string + Gateway string + DNS1 string + DNS2 string + Error string + HaveResult bool } func main() { - initPrefixAndTemplate() + initConfigAndTemplate() http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - renderPage(w, viewData{}) // empty form + renderPage(w, viewData{}) }) http.HandleFunc("/convert", func(w http.ResponseWriter, r *http.Request) { @@ -47,28 +72,33 @@ func main() { if err != nil { data.Error = err.Error() } else { + data.HaveResult = true data.IPv6 = ipv6 + data.Gateway = ulaPrefix + "1" // router IP = ::1 + data.DNS1 = dns1 + data.DNS2 = dns2 } renderPage(w, data) }) - log.Printf("Server läuft auf http://localhost%s (Präfix: %s)", listenAddr, ulaPrefix) + log.Printf("Server läuft auf http://localhost%s (Präfix %s, DNS1 %s, DNS2 %s)", listenAddr, ulaPrefix, dns1, dns2) log.Fatal(http.ListenAndServe(listenAddr, nil)) } -// initPrefixAndTemplate reads the environment variable and prepares the HTML template. -func initPrefixAndTemplate() { +// initConfigAndTemplate reads env vars and prepares HTML template. +func initConfigAndTemplate() { + // ---- ULA prefix ------------------------------------------------------- ulaPrefix = os.Getenv("ULA_PREFIX") if ulaPrefix == "" { ulaPrefix = defaultPrefix } - pageIP = os.Getenv("IPv4") + pageIP = os.Getenv("FORM_DEFAULT_IP") if pageIP == "" { pageIP = defaultIP } - // Ensure the prefix ends with exactly two colons (::) so that we can append hex words. + // ensure trailing :: so we can simply append hex words if !strings.HasSuffix(ulaPrefix, "::") { if strings.HasSuffix(ulaPrefix, ":") { ulaPrefix += ":" @@ -77,47 +107,102 @@ func initPrefixAndTemplate() { } } + // ---- DNS addresses ---------------------------------------------------- + dns1 = os.Getenv("DNS1") + dns2 = os.Getenv("DNS2") + + // default DNS: change subnet 0 → 1 and append ::53 / ::54 + if dns1 == "" { + dns1 = strings.Replace(ulaPrefix, "::", "::53", 1) + } + if dns2 == "" { + dns2 = strings.Replace(ulaPrefix, "::", "::54", 1) + } + + // ---- HTML template ---------------------------------------------------- html := fmt.Sprintf(` - -IPv4 → IPv6‑Mapper - + + IPv4 → IPv6‑Mapper + + -

IPv4 → IPv6-Mapper

-
- - -
- {{if .IPv6}} -
IPv6-Adresse: {{.IPv6}}
- {{end}} - {{if .Error}} -
Fehler: {{.Error}}
- {{end}} -

Präfix: %s   (/96‑Zuordnung)

+

IPv4 → IPv6‑Mapper

+
+ + +
+ + {{if .HaveResult}} +
+

Windows 11‑Eingaben

+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ {{end}} + + {{if .Error}} +

Fehler: {{.Error}}

+ {{end}} + +

Aktives Präfix: %s (/96)

`, pageIP, ulaPrefix) pageTemplate = template.Must(template.New("page").Parse(html)) } -// embedIPv4 converts a dotted IPv4 string into the chosen ULA /96 IPv6 address. +// embedIPv4 converts a dotted IPv4 string into an IPv6 address within ulaPrefix/96. func embedIPv4(ipv4 string) (string, error) { ip := net.ParseIP(ipv4).To4() if ip == nil { return "", fmt.Errorf("'%s' ist keine gültige IPv4-Adresse", ipv4) } - hi := uint16(ip[0])<<8 | uint16(ip[1]) // high 16 bits (octets 0–1) - lo := uint16(ip[2])<<8 | uint16(ip[3]) // low 16 bits (octets 2–3) + hi := uint16(ip[0])<<8 | uint16(ip[1]) + lo := uint16(ip[2])<<8 | uint16(ip[3]) return fmt.Sprintf("%s%x:%x", ulaPrefix, hi, lo), nil }