dhcp4d: make hostname override settable from status page
This commit is contained in:
parent
4f0efc7b18
commit
2b6ab5b2bd
@ -137,6 +137,9 @@ span.hostname-override {
|
|||||||
tr:nth-child(even) {
|
tr:nth-child(even) {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
}
|
}
|
||||||
|
form {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -152,7 +155,10 @@ tr:nth-child(even) {
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="ipaddr">{{$l.Addr}}</td>
|
<td class="ipaddr">{{$l.Addr}}</td>
|
||||||
<td>
|
<td>
|
||||||
{{$l.Hostname}}
|
<form action="/sethostname" method="post">
|
||||||
|
<input type="hidden" name="hardwareaddr" value="{{$l.HardwareAddr}}">
|
||||||
|
<input type="text" name="hostname" value="{{$l.Hostname}}">
|
||||||
|
</form>
|
||||||
{{ if (ne $l.HostnameOverride "") }}
|
{{ if (ne $l.HostnameOverride "") }}
|
||||||
<span class="hostname-override">!</span>
|
<span class="hostname-override">!</span>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
@ -258,6 +264,25 @@ func newSrv(permDir string) (*srv, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/sethostname", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "want POST", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hwaddr := r.FormValue("hardwareaddr")
|
||||||
|
if hwaddr == "" {
|
||||||
|
http.Error(w, "missing hardwareaddr parameter", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hostname := r.FormValue("hostname")
|
||||||
|
if hostname == "" {
|
||||||
|
http.Error(w, "missing hostname parameter", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handler.SetHostname(hwaddr, hostname)
|
||||||
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
|
})
|
||||||
|
|
||||||
http.HandleFunc("/lease/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/lease/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
hostname := strings.TrimPrefix(r.URL.Path, "/lease/")
|
hostname := strings.TrimPrefix(r.URL.Path, "/lease/")
|
||||||
if hostname == "" {
|
if hostname == "" {
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -49,8 +50,6 @@ type Handler struct {
|
|||||||
leaseRange int // number of IP addresses to hand out
|
leaseRange int // number of IP addresses to hand out
|
||||||
LeasePeriod time.Duration
|
LeasePeriod time.Duration
|
||||||
options dhcp4.Options
|
options dhcp4.Options
|
||||||
leasesHW map[string]int // points into leasesIP
|
|
||||||
leasesIP map[int]*Lease
|
|
||||||
rawConn net.PacketConn
|
rawConn net.PacketConn
|
||||||
iface *net.Interface
|
iface *net.Interface
|
||||||
|
|
||||||
@ -58,6 +57,10 @@ type Handler struct {
|
|||||||
|
|
||||||
// Leases is called whenever a new lease is handed out
|
// Leases is called whenever a new lease is handed out
|
||||||
Leases func([]*Lease, *Lease)
|
Leases func([]*Lease, *Lease)
|
||||||
|
|
||||||
|
leasesMu sync.Mutex
|
||||||
|
leasesHW map[string]int // points into leasesIP
|
||||||
|
leasesIP map[int]*Lease
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.PacketConn) (*Handler, error) {
|
func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.PacketConn) (*Handler, error) {
|
||||||
@ -105,6 +108,8 @@ func NewHandler(dir string, iface *net.Interface, ifaceName string, conn net.Pac
|
|||||||
// loaded from persistent storage. There is no locking, so SetLeases must be
|
// loaded from persistent storage. There is no locking, so SetLeases must be
|
||||||
// called before Serve.
|
// called before Serve.
|
||||||
func (h *Handler) SetLeases(leases []*Lease) {
|
func (h *Handler) SetLeases(leases []*Lease) {
|
||||||
|
h.leasesMu.Lock()
|
||||||
|
defer h.leasesMu.Unlock()
|
||||||
h.leasesHW = make(map[string]int)
|
h.leasesHW = make(map[string]int)
|
||||||
h.leasesIP = make(map[int]*Lease)
|
h.leasesIP = make(map[int]*Lease)
|
||||||
for _, l := range leases {
|
for _, l := range leases {
|
||||||
@ -113,7 +118,30 @@ func (h *Handler) SetLeases(leases []*Lease) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) callLeasesLocked(lease *Lease) {
|
||||||
|
if h.Leases == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var leases []*Lease
|
||||||
|
for _, l := range h.leasesIP {
|
||||||
|
leases = append(leases, l)
|
||||||
|
}
|
||||||
|
h.Leases(leases, lease)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) SetHostname(hwaddr, hostname string) {
|
||||||
|
h.leasesMu.Lock()
|
||||||
|
defer h.leasesMu.Unlock()
|
||||||
|
leaseNum := h.leasesHW[hwaddr]
|
||||||
|
lease := h.leasesIP[leaseNum]
|
||||||
|
lease.Hostname = hostname
|
||||||
|
lease.HostnameOverride = hostname
|
||||||
|
h.callLeasesLocked(lease)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handler) findLease() int {
|
func (h *Handler) findLease() int {
|
||||||
|
h.leasesMu.Lock()
|
||||||
|
defer h.leasesMu.Unlock()
|
||||||
now := h.timeNow()
|
now := h.timeNow()
|
||||||
if len(h.leasesIP) < h.leaseRange {
|
if len(h.leasesIP) < h.leaseRange {
|
||||||
// TODO: hash the hwaddr like dnsmasq
|
// TODO: hash the hwaddr like dnsmasq
|
||||||
@ -140,6 +168,8 @@ func (h *Handler) canLease(reqIP net.IP, hwaddr string) int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.leasesMu.Lock()
|
||||||
|
defer h.leasesMu.Unlock()
|
||||||
l, ok := h.leasesIP[leaseNum]
|
l, ok := h.leasesIP[leaseNum]
|
||||||
if !ok {
|
if !ok {
|
||||||
return leaseNum // lease available
|
return leaseNum // lease available
|
||||||
@ -156,6 +186,7 @@ func (h *Handler) canLease(reqIP net.IP, hwaddr string) int {
|
|||||||
return -1 // lease unavailable
|
return -1 // lease unavailable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServeDHCP is always called from the same goroutine, so no locking is required.
|
||||||
func (h *Handler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dhcp4.Options) dhcp4.Packet {
|
func (h *Handler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dhcp4.Options) dhcp4.Packet {
|
||||||
reply := h.serveDHCP(p, msgType, options)
|
reply := h.serveDHCP(p, msgType, options)
|
||||||
if reply == nil {
|
if reply == nil {
|
||||||
@ -205,6 +236,8 @@ func (h *Handler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) leaseHW(hwAddr string) (*Lease, bool) {
|
func (h *Handler) leaseHW(hwAddr string) (*Lease, bool) {
|
||||||
|
h.leasesMu.Lock()
|
||||||
|
defer h.leasesMu.Unlock()
|
||||||
num, ok := h.leasesHW[hwAddr]
|
num, ok := h.leasesHW[hwAddr]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
@ -284,18 +317,16 @@ func (h *Handler) serveDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Release any old leases for this client
|
// Release any old leases for this client
|
||||||
|
h.leasesMu.Lock()
|
||||||
delete(h.leasesIP, l.Num)
|
delete(h.leasesIP, l.Num)
|
||||||
|
h.leasesMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.leasesMu.Lock()
|
||||||
|
defer h.leasesMu.Unlock()
|
||||||
h.leasesIP[leaseNum] = lease
|
h.leasesIP[leaseNum] = lease
|
||||||
h.leasesHW[lease.HardwareAddr] = leaseNum
|
h.leasesHW[lease.HardwareAddr] = leaseNum
|
||||||
if h.Leases != nil {
|
h.callLeasesLocked(lease)
|
||||||
var leases []*Lease
|
|
||||||
for _, l := range h.leasesIP {
|
|
||||||
leases = append(leases, l)
|
|
||||||
}
|
|
||||||
h.Leases(leases, lease)
|
|
||||||
}
|
|
||||||
return dhcp4.ReplyPacket(p, dhcp4.ACK, h.serverIP, reqIP, h.LeasePeriod,
|
return dhcp4.ReplyPacket(p, dhcp4.ACK, h.serverIP, reqIP, h.LeasePeriod,
|
||||||
h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList]))
|
h.options.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList]))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user