Anpassungen für DHCPv6
All checks were successful
release-tag / release-image (push) Successful in 1m51s

This commit is contained in:
2025-05-09 22:48:51 +02:00
parent 2aa0a91dfc
commit c0db9f2f14

136
main.go
View File

@@ -20,12 +20,14 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"log" "log"
"net" "net"
"net/http" "net/http"
"os" "os"
"sort"
"strconv" "strconv"
"strings" "strings"
) )
@@ -47,6 +49,7 @@ var (
rangeLimit int rangeLimit int
singleTemplate *template.Template singleTemplate *template.Template
rangeTemplate *template.Template rangeTemplate *template.Template
dhcpTemplate *template.Template
dhcpServer string dhcpServer string
dhcpScope string dhcpScope string
dhcpNamePrefix string dhcpNamePrefix string
@@ -71,6 +74,105 @@ type rangeData struct {
HaveResult bool HaveResult bool
} }
var DuidHostnameList []payload
type payload struct {
Hostname string `json:"hostname"`
DUIDs []string `json:"duids"`
IAIDs []uint32 `json:"iaids"`
}
type payloadHelper struct {
Hostname string
DomainName string
DhcpServer string
DUID string
IAID string
CalculatedIPv4 string
Dhcp4Scope string
CalculatedIPv6 string
Dhcp6Scope string
}
func octetsRaw(ip string) ([]string, error) {
parts := strings.Split(ip, ".")
if len(parts) != 4 {
return nil, fmt.Errorf("ungültige IPv4-Adresse: %q", ip)
}
return parts, nil
}
func DhcpHelperFunc(xHostname string, xDUIDs []string, xIAIDs []uint32) []payloadHelper {
/*IPv4*/
Ipv4Octets, _ := octetsRaw(defaultIP)
rHostname := []rune(xHostname)
qDUID := xDUIDs[0]
qSegment1 := string(rHostname[2:4])
qSegment2 := string(rHostname[4:])
qCalculatedIPv4 := Ipv4Octets[0] + "." + Ipv4Octets[1] + "." + qSegment1 + "." + qSegment2
qCalculatedIPv6, _ := embedIPv4(qCalculatedIPv4)
var res []payloadHelper
for _, t := range xIAIDs {
r := payloadHelper{
Hostname: xHostname,
DUID: qDUID,
CalculatedIPv4: qCalculatedIPv4,
CalculatedIPv6: qCalculatedIPv6,
Dhcp4Scope: dhcpScope,
Dhcp6Scope: ulaPrefix,
DomainName: dhcpDomain,
DhcpServer: dhcpServer,
IAID: fmt.Sprintf("%d", t),
}
res = append(res, r)
}
return res
}
func getDhcp() []payloadHelper {
var result []payloadHelper
sortByHostname(DuidHostnameList)
for _, b := range DuidHostnameList {
result = append(result, DhcpHelperFunc(b.Hostname, b.DUIDs, b.IAIDs)...)
}
return result
}
func register(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "nur POST erlaubt", http.StatusMethodNotAllowed)
return
}
var p payload
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
http.Error(w, "ungültiges JSON", http.StatusBadRequest)
return
}
// --- hier kannst du speichern, weiterverarbeiten, loggen … ---
log.Printf("neuer Client: %s → DUIDs=%v", p.Hostname, p.DUIDs)
DuidHostnameList = append(DuidHostnameList, p)
w.WriteHeader(http.StatusNoContent) // 204
}
func getdhcp6(w http.ResponseWriter, r *http.Request) {
temp := getDhcp()
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_ = dhcpTemplate.Execute(w, temp)
}
func sortByHostname(p []payload) {
sort.Slice(p, func(i, j int) bool {
// Optional: case-insensitiv vergleichen
return strings.ToLower(p[i].Hostname) < strings.ToLower(p[j].Hostname)
})
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// main HTTP routing // main HTTP routing
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -80,6 +182,8 @@ func main() {
http.HandleFunc("/", handleSingle) http.HandleFunc("/", handleSingle)
http.HandleFunc("/convert", handleSingleConvert) http.HandleFunc("/convert", handleSingleConvert)
http.HandleFunc("/range", handleRange) http.HandleFunc("/range", handleRange)
http.HandleFunc("/register", register)
http.HandleFunc("/dhcp6", getdhcp6)
log.Printf("Server läuft auf http://localhost%s (Präfix %s, DNS1 %s, DNS2 %s, Limit %d)", listenAddr, ulaPrefix, dns1, dns2, rangeLimit) log.Printf("Server läuft auf http://localhost%s (Präfix %s, DNS1 %s, DNS2 %s, Limit %d)", listenAddr, ulaPrefix, dns1, dns2, rangeLimit)
log.Fatal(http.ListenAndServe(listenAddr, nil)) log.Fatal(http.ListenAndServe(listenAddr, nil))
@@ -132,8 +236,8 @@ func handleRange(w http.ResponseWriter, r *http.Request) {
d.Error = err.Error() d.Error = err.Error()
} else { } else {
d.HaveResult = true d.HaveResult = true
for a, b := range rows { for _, b := range rows {
fmt.Println(a, b) //fmt.Println(a, b)
octets := strings.Split(b.IPv4, ".") octets := strings.Split(b.IPv4, ".")
if len(octets) != 4 { if len(octets) != 4 {
fmt.Println("Ungültige IP-Adresse!") fmt.Println("Ungültige IP-Adresse!")
@@ -262,10 +366,11 @@ func initConfigAndTemplates() {
rangeHTML := rangePageHTML rangeHTML := rangePageHTML
singleTemplate = template.Must(template.New("single").Parse(singleHTML)) singleTemplate = template.Must(template.New("single").Parse(singleHTML))
rangeTemplate = template.Must(template.New("range").Parse(rangeHTML)) rangeTemplate = template.Must(template.New("range").Parse(rangeHTML))
dhcpTemplate = template.Must(template.New("range").Parse(rangeDHCP6HTML))
fmt.Println(ulaPrefix, dns1, dns2, pageIP, dhcpServer, dhcpScope, rangeLimit) fmt.Println(ulaPrefix, dns1, dns2, pageIP, dhcpServer, dhcpScope, rangeLimit)
fmt.Println(singleHTML) //fmt.Println(singleHTML)
fmt.Println(rangeHTML) //fmt.Println(rangeHTML)
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -349,3 +454,26 @@ var rangePageHTML = `<!DOCTYPE html>
{{end}} {{end}}
{{if .Error}}<p style="color:#b00">Fehler: {{.Error}}</p>{{end}} {{if .Error}}<p style="color:#b00">Fehler: {{.Error}}</p>{{end}}
</body></html>` </body></html>`
var rangeDHCP6HTML = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<title>DHCP-IPv6</title>
<style>
body{font-family:system-ui,sans-serif;margin:2rem}
table{border-collapse:collapse;width:100%}
th,td{border:1px solid #ccc;padding:.4rem;text-align:left;font-family:monospace}
form{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}
input[type=text]{padding:.4rem;font-size:1rem;border:1px solid #ccc;border-radius:4px;flex:1}
button{padding:.5rem 1rem;font-size:1rem;cursor:pointer;border-radius:4px;border:1px solid #666;background:#eee}
</style>
</head><body>
<h1>DHCPv6 - DUID-Registrierung</h1>
<table>
<tr><th>Hostname</th><th>Duid</th><th>IPv4</th><th>IPv6</th><th>DHCP6</th></tr>
{{range .}}<tr><td>{{.Hostname}}</td><td>{{.DUID}}</td><td>{{.CalculatedIPv4}}</td><td>{{.CalculatedIPv6}}</td><td>Add-DhcpServerv6Reservation -ComputerName {{.DhcpServer}} -Prefix {{.Dhcp6Scope}} -IPAddress {{.CalculatedIPv6}} -ClientDuid {{.DUID}} -Iaid {{.IAID}} -Name {{.Hostname}}.{{.DomainName}} -Description "Auto-reserved after rollout"</td></tr>{{end}}
</table>
</body></html>`
//Add-DhcpServerv6Reservation -ComputerName $Srv -Prefix $Prefix -IPAddress IPv6Address -ClientDuid $l.ClientDuid -Iaid $l.Iaid -Name $l.HostName -Description "Auto-reserved after rollout"