Files
ipv6calculator/main.go
jbergner b4e90b1e92
All checks were successful
release-tag / release-image (push) Successful in 1m54s
ENV Anpassung
2025-05-09 08:29:11 +02:00

130 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"html/template"
"log"
"net"
"net/http"
"os"
"strings"
)
const (
listenAddr = ":8080" // TCP port for the web UI
defaultPrefix = "fdcb:7de3:a12a:0::" // fallback when ULA_PREFIX is unset
defaultIP = "172.16.0.0"
)
var (
ulaPrefix string // effective /96 prefix (always ending in "::")
pageTemplate *template.Template // populated in init()
pageIP string
)
// viewData feeds data into the HTML template.
type viewData struct {
IPv4 string
IPv6 string
Error string
}
func main() {
initPrefixAndTemplate()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
renderPage(w, viewData{}) // empty form
})
http.HandleFunc("/convert", func(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
renderPage(w, viewData{Error: "Ungültiges Formular"})
return
}
ipv4Str := r.FormValue("ipv4")
ipv6, err := embedIPv4(ipv4Str)
data := viewData{IPv4: ipv4Str}
if err != nil {
data.Error = err.Error()
} else {
data.IPv6 = ipv6
}
renderPage(w, data)
})
log.Printf("Server läuft auf http://localhost%s (Präfix: %s)", listenAddr, ulaPrefix)
log.Fatal(http.ListenAndServe(listenAddr, nil))
}
// initPrefixAndTemplate reads the environment variable and prepares the HTML template.
func initPrefixAndTemplate() {
ulaPrefix = os.Getenv("ULA_PREFIX")
if ulaPrefix == "" {
ulaPrefix = defaultPrefix
}
pageIP = os.Getenv("IPv4")
if pageIP == "" {
pageIP = defaultIP
}
// Ensure the prefix ends with exactly two colons (::) so that we can append hex words.
if !strings.HasSuffix(ulaPrefix, "::") {
if strings.HasSuffix(ulaPrefix, ":") {
ulaPrefix += ":"
} else {
ulaPrefix += "::"
}
}
html := fmt.Sprintf(`<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<title>IPv4 → IPv6Mapper</title>
<style>
body { font-family: system-ui, sans-serif; margin: 2rem; }
form { display: flex; gap: .5rem; }
input[type=text] { flex: 1; padding: .4rem; font-size: 1rem; }
button { padding: .5rem 1rem; font-size: 1rem; cursor: pointer; }
#result { margin-top: 1.5rem; font-weight: bold; }
.error { color: #b00; }
</style>
</head>
<body>
<h1>IPv4 → IPv6-Mapper</h1>
<form action="/convert" method="post">
<input type="text" name="ipv4" placeholder="%s" value="{{.IPv4}}" required />
<button type="submit">Umrechnen</button>
</form>
{{if .IPv6}}
<div id="result">IPv6-Adresse: <code>{{.IPv6}}</code></div>
{{end}}
{{if .Error}}
<div class="error">Fehler: {{.Error}}</div>
{{end}}
<p>Präfix: <code>%s</code> &nbsp; (/96Zuordnung)</p>
</body>
</html>`, pageIP, ulaPrefix)
pageTemplate = template.Must(template.New("page").Parse(html))
}
// embedIPv4 converts a dotted IPv4 string into the chosen ULA /96 IPv6 address.
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 01)
lo := uint16(ip[2])<<8 | uint16(ip[3]) // low 16 bits (octets 23)
return fmt.Sprintf("%s%x:%x", ulaPrefix, hi, lo), nil
}
func renderPage(w http.ResponseWriter, d viewData) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := pageTemplate.Execute(w, d); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}