mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2025-02-26 06:49:02 +03:00
dummy build on windows; move code
This commit is contained in:
parent
b8a5661277
commit
f99b4f07e9
10 changed files with 494 additions and 149 deletions
|
@ -395,7 +395,7 @@ Response:
|
||||||
200 OK
|
200 OK
|
||||||
|
|
||||||
{
|
{
|
||||||
"config":{
|
"v4":{
|
||||||
"enabled":false,
|
"enabled":false,
|
||||||
"interface_name":"...",
|
"interface_name":"...",
|
||||||
"gateway_ip":"...",
|
"gateway_ip":"...",
|
||||||
|
@ -405,7 +405,7 @@ Response:
|
||||||
"lease_duration":60,
|
"lease_duration":60,
|
||||||
"icmp_timeout_msec":0
|
"icmp_timeout_msec":0
|
||||||
},
|
},
|
||||||
"config_v6":{
|
"v6":{
|
||||||
"enabled":false,
|
"enabled":false,
|
||||||
"range_start":"...",
|
"range_start":"...",
|
||||||
"lease_duration":60,
|
"lease_duration":60,
|
||||||
|
@ -468,16 +468,17 @@ Request:
|
||||||
POST /control/dhcp/set_config
|
POST /control/dhcp/set_config
|
||||||
|
|
||||||
{
|
{
|
||||||
"enabled":true,
|
"v4":{
|
||||||
"interface_name":"vboxnet0",
|
"enabled":true,
|
||||||
|
"interface_name":"vboxnet0",
|
||||||
"gateway_ip":"192.169.56.1",
|
|
||||||
"subnet_mask":"255.255.255.0",
|
|
||||||
"range_start":"192.169.56.100",
|
|
||||||
"range_end":"192.169.56.200",
|
|
||||||
"lease_duration":60,
|
|
||||||
"icmp_timeout_msec":0,
|
|
||||||
|
|
||||||
|
"gateway_ip":"192.169.56.1",
|
||||||
|
"subnet_mask":"255.255.255.0",
|
||||||
|
"range_start":"192.169.56.100",
|
||||||
|
"range_end":"192.169.56.200",
|
||||||
|
"lease_duration":60,
|
||||||
|
"icmp_timeout_msec":0,
|
||||||
|
},
|
||||||
"v6":{
|
"v6":{
|
||||||
"enabled":false,
|
"enabled":false,
|
||||||
"range_start":"...",
|
"range_start":"...",
|
||||||
|
|
|
@ -40,6 +40,43 @@ func convertLeases(inputLeases []Lease, includeExpires bool) []map[string]string
|
||||||
return leases
|
return leases
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type v4ServerConfJSON struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
InterfaceName string `json:"interface_name"`
|
||||||
|
GatewayIP string `json:"gateway_ip"`
|
||||||
|
SubnetMask string `json:"subnet_mask"`
|
||||||
|
RangeStart string `json:"range_start"`
|
||||||
|
RangeEnd string `json:"range_end"`
|
||||||
|
LeaseDuration uint32 `json:"lease_duration"`
|
||||||
|
ICMPTimeout uint32 `json:"icmp_timeout_msec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func v4ServerConfToJSON(c V4ServerConf) v4ServerConfJSON {
|
||||||
|
return v4ServerConfJSON{
|
||||||
|
Enabled: c.Enabled,
|
||||||
|
InterfaceName: c.InterfaceName,
|
||||||
|
GatewayIP: c.GatewayIP,
|
||||||
|
SubnetMask: c.SubnetMask,
|
||||||
|
RangeStart: c.RangeStart,
|
||||||
|
RangeEnd: c.RangeEnd,
|
||||||
|
LeaseDuration: c.LeaseDuration,
|
||||||
|
ICMPTimeout: c.ICMPTimeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func v4JSONToServerConf(c v4ServerConfJSON) V4ServerConf {
|
||||||
|
return V4ServerConf{
|
||||||
|
Enabled: c.Enabled,
|
||||||
|
InterfaceName: c.InterfaceName,
|
||||||
|
GatewayIP: c.GatewayIP,
|
||||||
|
SubnetMask: c.SubnetMask,
|
||||||
|
RangeStart: c.RangeStart,
|
||||||
|
RangeEnd: c.RangeEnd,
|
||||||
|
LeaseDuration: c.LeaseDuration,
|
||||||
|
ICMPTimeout: c.ICMPTimeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type v6ServerConfJSON struct {
|
type v6ServerConfJSON struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
RangeStart string `json:"range_start"`
|
RangeStart string `json:"range_start"`
|
||||||
|
@ -66,8 +103,8 @@ func (s *Server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
leases := convertLeases(s.Leases(LeasesDynamic), true)
|
leases := convertLeases(s.Leases(LeasesDynamic), true)
|
||||||
staticLeases := convertLeases(s.Leases(LeasesStatic), false)
|
staticLeases := convertLeases(s.Leases(LeasesStatic), false)
|
||||||
status := map[string]interface{}{
|
status := map[string]interface{}{
|
||||||
"config": s.conf.Conf4,
|
"v4": v4ServerConfToJSON(s.conf.Conf4),
|
||||||
"config_v6": v6ServerConfToJSON(s.conf.Conf6),
|
"v6": v6ServerConfToJSON(s.conf.Conf6),
|
||||||
"leases": leases,
|
"leases": leases,
|
||||||
"static_leases": staticLeases,
|
"static_leases": staticLeases,
|
||||||
}
|
}
|
||||||
|
@ -87,8 +124,8 @@ type staticLeaseJSON struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type dhcpServerConfigJSON struct {
|
type dhcpServerConfigJSON struct {
|
||||||
V4ServerConf `json:",inline"`
|
V4 v4ServerConfJSON `json:"v4"`
|
||||||
V6 v6ServerConfJSON `json:"v6"`
|
V6 v6ServerConfJSON `json:"v6"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -110,7 +147,7 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Error("failed to stop the DHCP server: %s", err)
|
log.Error("failed to stop the DHCP server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
v4conf := newconfig.V4ServerConf
|
v4conf := v4JSONToServerConf(newconfig.V4)
|
||||||
v4conf.notify = s.conf.Conf4.notify
|
v4conf.notify = s.conf.Conf4.notify
|
||||||
s4, err := v4Create(v4conf)
|
s4, err := v4Create(v4conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -131,10 +168,10 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
s.conf.ConfigModified()
|
s.conf.ConfigModified()
|
||||||
|
|
||||||
if newconfig.Enabled {
|
if newconfig.V4.Enabled {
|
||||||
staticIP, err := HasStaticIP(newconfig.InterfaceName)
|
staticIP, err := HasStaticIP(newconfig.V4.InterfaceName)
|
||||||
if !staticIP && err == nil {
|
if !staticIP && err == nil {
|
||||||
err = SetStaticIP(newconfig.InterfaceName)
|
err = SetStaticIP(newconfig.V4.InterfaceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(r, w, http.StatusInternalServerError, "Failed to configure static IP: %s", err)
|
httpError(r, w, http.StatusInternalServerError, "Failed to configure static IP: %s", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -56,8 +56,8 @@ const (
|
||||||
|
|
||||||
// Server - the current state of the DHCP server
|
// Server - the current state of the DHCP server
|
||||||
type Server struct {
|
type Server struct {
|
||||||
srv4 *V4Server
|
srv4 DHCPServer
|
||||||
srv6 *V6Server
|
srv6 DHCPServer
|
||||||
|
|
||||||
conf ServerConfig
|
conf ServerConfig
|
||||||
|
|
||||||
|
@ -75,6 +75,8 @@ func Create(config ServerConfig) *Server {
|
||||||
s := Server{}
|
s := Server{}
|
||||||
config.Conf4.notify = s.onNotify
|
config.Conf4.notify = s.onNotify
|
||||||
config.Conf6.notify = s.onNotify
|
config.Conf6.notify = s.onNotify
|
||||||
|
s.conf.HTTPRegister = config.HTTPRegister
|
||||||
|
s.conf.ConfigModified = config.ConfigModified
|
||||||
s.conf.DBFilePath = filepath.Join(config.WorkDir, dbFilename)
|
s.conf.DBFilePath = filepath.Join(config.WorkDir, dbFilename)
|
||||||
|
|
||||||
if !webHandlersRegistered && s.conf.HTTPRegister != nil {
|
if !webHandlersRegistered && s.conf.HTTPRegister != nil {
|
||||||
|
@ -84,13 +86,13 @@ func Create(config ServerConfig) *Server {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
s.srv4, err = v4Create(config.Conf4)
|
s.srv4, err = v4Create(config.Conf4)
|
||||||
if s.srv4 == nil {
|
if err != nil {
|
||||||
log.Error("%s", err)
|
log.Error("%s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.srv6, err = v6Create(config.Conf6)
|
s.srv6, err = v6Create(config.Conf6)
|
||||||
if s.srv6 == nil {
|
if err != nil {
|
||||||
log.Error("%s", err)
|
log.Error("%s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -125,8 +127,8 @@ func (s *Server) notify(flags int) {
|
||||||
|
|
||||||
// WriteDiskConfig - write configuration
|
// WriteDiskConfig - write configuration
|
||||||
func (s *Server) WriteDiskConfig(c *ServerConfig) {
|
func (s *Server) WriteDiskConfig(c *ServerConfig) {
|
||||||
s.srv4.WriteDiskConfig(&c.Conf4)
|
s.srv4.WriteDiskConfig4(&c.Conf4)
|
||||||
s.srv6.WriteDiskConfig(&c.Conf6)
|
s.srv6.WriteDiskConfig6(&c.Conf6)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start will listen on port 67 and serve DHCP requests.
|
// Start will listen on port 67 and serve DHCP requests.
|
||||||
|
@ -170,11 +172,6 @@ func (s *Server) Leases(flags int) []Lease {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddStaticLease adds a static lease (thread-safe)
|
|
||||||
func (s *Server) AddStaticLease(lease Lease) error {
|
|
||||||
return s.srv4.AddStaticLease(lease)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases
|
// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases
|
||||||
func (s *Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
func (s *Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
||||||
if ip.To4() != nil {
|
if ip.To4() != nil {
|
||||||
|
|
|
@ -39,6 +39,26 @@ func parseIPv4(text string) (net.IP, error) {
|
||||||
return result.To4(), nil
|
return result.To4(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get IPv4 address list
|
||||||
|
func getIfaceIPv4(iface net.Interface) []net.IP {
|
||||||
|
addrs, err := iface.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []net.IP
|
||||||
|
for _, a := range addrs {
|
||||||
|
ipnet, ok := a.(*net.IPNet)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ipnet.IP.To4() != nil {
|
||||||
|
res = append(res, ipnet.IP.To4())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
// Return TRUE if subnet mask is correct (e.g. 255.255.255.0)
|
// Return TRUE if subnet mask is correct (e.g. 255.255.255.0)
|
||||||
func isValidSubnetMask(mask net.IP) bool {
|
func isValidSubnetMask(mask net.IP) bool {
|
||||||
var n uint32
|
var n uint32
|
||||||
|
|
61
dhcpd/server.go
Normal file
61
dhcpd/server.go
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package dhcpd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DHCPServer - DHCP server interface
|
||||||
|
type DHCPServer interface {
|
||||||
|
ResetLeases(leases []*Lease)
|
||||||
|
GetLeases(flags int) []Lease
|
||||||
|
GetLeasesRef() []*Lease
|
||||||
|
AddStaticLease(lease Lease) error
|
||||||
|
RemoveStaticLease(l Lease) error
|
||||||
|
FindMACbyIP(ip net.IP) net.HardwareAddr
|
||||||
|
|
||||||
|
WriteDiskConfig4(c *V4ServerConf)
|
||||||
|
WriteDiskConfig6(c *V6ServerConf)
|
||||||
|
|
||||||
|
Start() error
|
||||||
|
Stop()
|
||||||
|
Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// V4ServerConf - server configuration
|
||||||
|
type V4ServerConf struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
InterfaceName string `yaml:"interface_name"` // eth0, en0 and so on
|
||||||
|
GatewayIP string `yaml:"gateway_ip"`
|
||||||
|
SubnetMask string `yaml:"subnet_mask"`
|
||||||
|
RangeStart string `yaml:"range_start"`
|
||||||
|
RangeEnd string `yaml:"range_end"`
|
||||||
|
LeaseDuration uint32 `yaml:"lease_duration"` // in seconds
|
||||||
|
|
||||||
|
// IP conflict detector: time (ms) to wait for ICMP reply.
|
||||||
|
// 0: disable
|
||||||
|
ICMPTimeout uint32 `yaml:"icmp_timeout_msec"`
|
||||||
|
|
||||||
|
ipStart net.IP
|
||||||
|
ipEnd net.IP
|
||||||
|
leaseTime time.Duration
|
||||||
|
dnsIPAddrs []net.IP // IPv4 addresses to return to DHCP clients as DNS server addresses
|
||||||
|
routerIP net.IP
|
||||||
|
subnetMask net.IPMask
|
||||||
|
|
||||||
|
notify func(uint32)
|
||||||
|
}
|
||||||
|
|
||||||
|
// V6ServerConf - server configuration
|
||||||
|
type V6ServerConf struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
InterfaceName string `yaml:"interface_name"`
|
||||||
|
RangeStart string `yaml:"range_start"`
|
||||||
|
LeaseDuration uint32 `yaml:"lease_duration"` // in seconds
|
||||||
|
|
||||||
|
ipStart net.IP
|
||||||
|
leaseTime time.Duration
|
||||||
|
dnsIPAddrs []net.IP // IPv6 addresses to return to DHCP clients as DNS server addresses
|
||||||
|
|
||||||
|
notify func(uint32)
|
||||||
|
}
|
111
dhcpd/v4.go
111
dhcpd/v4.go
|
@ -1,3 +1,5 @@
|
||||||
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
package dhcpd
|
package dhcpd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -14,8 +16,8 @@ import (
|
||||||
"github.com/sparrc/go-ping"
|
"github.com/sparrc/go-ping"
|
||||||
)
|
)
|
||||||
|
|
||||||
// V4Server - DHCPv4 server
|
// v4Server - DHCPv4 server
|
||||||
type V4Server struct {
|
type v4Server struct {
|
||||||
srv *server4.Server
|
srv *server4.Server
|
||||||
leasesLock sync.Mutex
|
leasesLock sync.Mutex
|
||||||
leases []*Lease
|
leases []*Lease
|
||||||
|
@ -24,37 +26,20 @@ type V4Server struct {
|
||||||
conf V4ServerConf
|
conf V4ServerConf
|
||||||
}
|
}
|
||||||
|
|
||||||
// V4ServerConf - server configuration
|
// WriteDiskConfig4 - write configuration
|
||||||
type V4ServerConf struct {
|
func (s *v4Server) WriteDiskConfig4(c *V4ServerConf) {
|
||||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
*c = s.conf
|
||||||
InterfaceName string `json:"interface_name" yaml:"interface_name"` // eth0, en0 and so on
|
|
||||||
GatewayIP string `json:"gateway_ip" yaml:"gateway_ip"`
|
|
||||||
SubnetMask string `json:"subnet_mask" yaml:"subnet_mask"`
|
|
||||||
RangeStart string `json:"range_start" yaml:"range_start"`
|
|
||||||
RangeEnd string `json:"range_end" yaml:"range_end"`
|
|
||||||
LeaseDuration uint32 `json:"lease_duration" yaml:"lease_duration"` // in seconds
|
|
||||||
|
|
||||||
// IP conflict detector: time (ms) to wait for ICMP reply.
|
|
||||||
// 0: disable
|
|
||||||
ICMPTimeout uint32 `json:"icmp_timeout_msec" yaml:"icmp_timeout_msec"`
|
|
||||||
|
|
||||||
ipStart net.IP
|
|
||||||
ipEnd net.IP
|
|
||||||
leaseTime time.Duration
|
|
||||||
dnsIPAddrs []net.IP // IPv4 addresses to return to DHCP clients as DNS server addresses
|
|
||||||
routerIP net.IP
|
|
||||||
subnetMask net.IPMask
|
|
||||||
|
|
||||||
notify func(uint32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteDiskConfig - write configuration
|
// WriteDiskConfig6 - write configuration
|
||||||
func (s *V4Server) WriteDiskConfig(c *V4ServerConf) {
|
func (s *v4Server) WriteDiskConfig6(c *V6ServerConf) {
|
||||||
*c = s.conf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return TRUE if IP address is within range [start..stop]
|
// Return TRUE if IP address is within range [start..stop]
|
||||||
func ipInRange(start net.IP, stop net.IP, ip net.IP) bool {
|
func ipInRange(start net.IP, stop net.IP, ip net.IP) bool {
|
||||||
|
if len(start) != 4 || len(stop) != 4 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
from := binary.BigEndian.Uint32(start)
|
from := binary.BigEndian.Uint32(start)
|
||||||
to := binary.BigEndian.Uint32(stop)
|
to := binary.BigEndian.Uint32(stop)
|
||||||
check := binary.BigEndian.Uint32(ip)
|
check := binary.BigEndian.Uint32(ip)
|
||||||
|
@ -62,7 +47,7 @@ func ipInRange(start net.IP, stop net.IP, ip net.IP) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetLeases - reset leases
|
// ResetLeases - reset leases
|
||||||
func (s *V4Server) ResetLeases(leases []*Lease) {
|
func (s *v4Server) ResetLeases(leases []*Lease) {
|
||||||
s.leases = nil
|
s.leases = nil
|
||||||
|
|
||||||
for _, l := range leases {
|
for _, l := range leases {
|
||||||
|
@ -79,12 +64,12 @@ func (s *V4Server) ResetLeases(leases []*Lease) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLeasesRef - get leases
|
// GetLeasesRef - get leases
|
||||||
func (s *V4Server) GetLeasesRef() []*Lease {
|
func (s *v4Server) GetLeasesRef() []*Lease {
|
||||||
return s.leases
|
return s.leases
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLeases returns the list of current DHCP leases (thread-safe)
|
// GetLeases returns the list of current DHCP leases (thread-safe)
|
||||||
func (s *V4Server) GetLeases(flags int) []Lease {
|
func (s *v4Server) GetLeases(flags int) []Lease {
|
||||||
var result []Lease
|
var result []Lease
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
@ -101,7 +86,7 @@ func (s *V4Server) GetLeases(flags int) []Lease {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases
|
// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases
|
||||||
func (s *V4Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
func (s *v4Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
|
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
|
@ -124,7 +109,7 @@ func (s *V4Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the specified IP to the black list for a time period
|
// Add the specified IP to the black list for a time period
|
||||||
func (s *V4Server) blacklistLease(lease *Lease) {
|
func (s *v4Server) blacklistLease(lease *Lease) {
|
||||||
hw := make(net.HardwareAddr, 6)
|
hw := make(net.HardwareAddr, 6)
|
||||||
lease.HWAddr = hw
|
lease.HWAddr = hw
|
||||||
lease.Hostname = ""
|
lease.Hostname = ""
|
||||||
|
@ -132,7 +117,7 @@ func (s *V4Server) blacklistLease(lease *Lease) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove (swap) lease by index
|
// Remove (swap) lease by index
|
||||||
func (s *V4Server) leaseRemoveSwapByIndex(i int) {
|
func (s *v4Server) leaseRemoveSwapByIndex(i int) {
|
||||||
s.ipAddrs[s.leases[i].IP[3]] = 0
|
s.ipAddrs[s.leases[i].IP[3]] = 0
|
||||||
log.Debug("DHCPv4: removed lease %s", s.leases[i].HWAddr)
|
log.Debug("DHCPv4: removed lease %s", s.leases[i].HWAddr)
|
||||||
|
|
||||||
|
@ -145,7 +130,7 @@ func (s *V4Server) leaseRemoveSwapByIndex(i int) {
|
||||||
|
|
||||||
// Remove a dynamic lease with the same properties
|
// Remove a dynamic lease with the same properties
|
||||||
// Return error if a static lease is found
|
// Return error if a static lease is found
|
||||||
func (s *V4Server) rmDynamicLease(lease Lease) error {
|
func (s *v4Server) rmDynamicLease(lease Lease) error {
|
||||||
for i := 0; i < len(s.leases); i++ {
|
for i := 0; i < len(s.leases); i++ {
|
||||||
l := s.leases[i]
|
l := s.leases[i]
|
||||||
|
|
||||||
|
@ -172,14 +157,14 @@ func (s *V4Server) rmDynamicLease(lease Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a lease
|
// Add a lease
|
||||||
func (s *V4Server) addLease(l *Lease) {
|
func (s *v4Server) addLease(l *Lease) {
|
||||||
s.leases = append(s.leases, l)
|
s.leases = append(s.leases, l)
|
||||||
s.ipAddrs[l.IP[3]] = 1
|
s.ipAddrs[l.IP[3]] = 1
|
||||||
log.Debug("DHCPv4: added lease %s <-> %s", l.IP, l.HWAddr)
|
log.Debug("DHCPv4: added lease %s <-> %s", l.IP, l.HWAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a lease with the same properties
|
// Remove a lease with the same properties
|
||||||
func (s *V4Server) rmLease(lease Lease) error {
|
func (s *v4Server) rmLease(lease Lease) error {
|
||||||
for i, l := range s.leases {
|
for i, l := range s.leases {
|
||||||
if net.IP.Equal(l.IP, lease.IP) {
|
if net.IP.Equal(l.IP, lease.IP) {
|
||||||
|
|
||||||
|
@ -197,7 +182,7 @@ func (s *V4Server) rmLease(lease Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddStaticLease adds a static lease (thread-safe)
|
// AddStaticLease adds a static lease (thread-safe)
|
||||||
func (s *V4Server) AddStaticLease(lease Lease) error {
|
func (s *v4Server) AddStaticLease(lease Lease) error {
|
||||||
if len(lease.IP) != 4 {
|
if len(lease.IP) != 4 {
|
||||||
return fmt.Errorf("invalid IP")
|
return fmt.Errorf("invalid IP")
|
||||||
}
|
}
|
||||||
|
@ -221,7 +206,7 @@ func (s *V4Server) AddStaticLease(lease Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveStaticLease removes a static lease (thread-safe)
|
// RemoveStaticLease removes a static lease (thread-safe)
|
||||||
func (s *V4Server) RemoveStaticLease(l Lease) error {
|
func (s *v4Server) RemoveStaticLease(l Lease) error {
|
||||||
if len(l.IP) != 4 {
|
if len(l.IP) != 4 {
|
||||||
return fmt.Errorf("invalid IP")
|
return fmt.Errorf("invalid IP")
|
||||||
}
|
}
|
||||||
|
@ -244,7 +229,7 @@ func (s *V4Server) RemoveStaticLease(l Lease) error {
|
||||||
|
|
||||||
// Send ICMP to the specified machine
|
// Send ICMP to the specified machine
|
||||||
// Return TRUE if it doesn't reply, which probably means that the IP is available
|
// Return TRUE if it doesn't reply, which probably means that the IP is available
|
||||||
func (s *V4Server) addrAvailable(target net.IP) bool {
|
func (s *v4Server) addrAvailable(target net.IP) bool {
|
||||||
|
|
||||||
if s.conf.ICMPTimeout == 0 {
|
if s.conf.ICMPTimeout == 0 {
|
||||||
return true
|
return true
|
||||||
|
@ -276,7 +261,7 @@ func (s *V4Server) addrAvailable(target net.IP) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find lease by MAC
|
// Find lease by MAC
|
||||||
func (s *V4Server) findLease(mac net.HardwareAddr) *Lease {
|
func (s *v4Server) findLease(mac net.HardwareAddr) *Lease {
|
||||||
for i := range s.leases {
|
for i := range s.leases {
|
||||||
if bytes.Equal(mac, s.leases[i].HWAddr) {
|
if bytes.Equal(mac, s.leases[i].HWAddr) {
|
||||||
return s.leases[i]
|
return s.leases[i]
|
||||||
|
@ -286,7 +271,7 @@ func (s *V4Server) findLease(mac net.HardwareAddr) *Lease {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get next free IP
|
// Get next free IP
|
||||||
func (s *V4Server) findFreeIP() net.IP {
|
func (s *v4Server) findFreeIP() net.IP {
|
||||||
for i := s.conf.ipStart[3]; ; i++ {
|
for i := s.conf.ipStart[3]; ; i++ {
|
||||||
if s.ipAddrs[i] == 0 {
|
if s.ipAddrs[i] == 0 {
|
||||||
ip := make([]byte, 4)
|
ip := make([]byte, 4)
|
||||||
|
@ -302,7 +287,7 @@ func (s *V4Server) findFreeIP() net.IP {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find an expired lease and return its index or -1
|
// Find an expired lease and return its index or -1
|
||||||
func (s *V4Server) findExpiredLease() int {
|
func (s *v4Server) findExpiredLease() int {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
for i, lease := range s.leases {
|
for i, lease := range s.leases {
|
||||||
if lease.Expiry.Unix() != leaseExpireStatic &&
|
if lease.Expiry.Unix() != leaseExpireStatic &&
|
||||||
|
@ -314,7 +299,7 @@ func (s *V4Server) findExpiredLease() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve lease for MAC
|
// Reserve lease for MAC
|
||||||
func (s *V4Server) reserveLease(mac net.HardwareAddr) *Lease {
|
func (s *v4Server) reserveLease(mac net.HardwareAddr) *Lease {
|
||||||
l := Lease{}
|
l := Lease{}
|
||||||
l.HWAddr = make([]byte, 6)
|
l.HWAddr = make([]byte, 6)
|
||||||
copy(l.HWAddr, mac)
|
copy(l.HWAddr, mac)
|
||||||
|
@ -334,7 +319,7 @@ func (s *V4Server) reserveLease(mac net.HardwareAddr) *Lease {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process Discover request and return lease
|
// Process Discover request and return lease
|
||||||
func (s *V4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lease {
|
func (s *v4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lease {
|
||||||
mac := req.ClientHWAddr
|
mac := req.ClientHWAddr
|
||||||
|
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
|
@ -384,7 +369,7 @@ func (s *V4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lea
|
||||||
|
|
||||||
// Process Request request and return lease
|
// Process Request request and return lease
|
||||||
// Return false if we don't need to reply
|
// Return false if we don't need to reply
|
||||||
func (s *V4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lease, bool) {
|
func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lease, bool) {
|
||||||
var lease *Lease
|
var lease *Lease
|
||||||
mac := req.ClientHWAddr
|
mac := req.ClientHWAddr
|
||||||
hostname := req.Options.Get(dhcpv4.OptionHostName)
|
hostname := req.Options.Get(dhcpv4.OptionHostName)
|
||||||
|
@ -450,7 +435,7 @@ func (s *V4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
|
||||||
// Return 1: OK
|
// Return 1: OK
|
||||||
// Return 0: error; reply with Nak
|
// Return 0: error; reply with Nak
|
||||||
// Return -1: error; don't reply
|
// Return -1: error; don't reply
|
||||||
func (s *V4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
|
func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
|
||||||
|
|
||||||
var lease *Lease
|
var lease *Lease
|
||||||
|
|
||||||
|
@ -489,7 +474,7 @@ func (s *V4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
|
||||||
// client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,Offer,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67)
|
// client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,Offer,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67)
|
||||||
// client(0.0.0.0:68) -> (Request:ClientMAC,Request,ClientID,ReqIP,HostName,ServerID,ParamReqList) -> server(255.255.255.255:67)
|
// client(0.0.0.0:68) -> (Request:ClientMAC,Request,ClientID,ReqIP,HostName,ServerID,ParamReqList) -> server(255.255.255.255:67)
|
||||||
// client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,ACK,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67)
|
// client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,ACK,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67)
|
||||||
func (s *V4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4.DHCPv4) {
|
func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4.DHCPv4) {
|
||||||
log.Debug("DHCPv4: received message: %s", req.Summary())
|
log.Debug("DHCPv4: received message: %s", req.Summary())
|
||||||
|
|
||||||
switch req.MessageType() {
|
switch req.MessageType() {
|
||||||
|
@ -529,28 +514,8 @@ func (s *V4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get IPv4 address list
|
|
||||||
func getIfaceIPv4(iface net.Interface) []net.IP {
|
|
||||||
addrs, err := iface.Addrs()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var res []net.IP
|
|
||||||
for _, a := range addrs {
|
|
||||||
ipnet, ok := a.(*net.IPNet)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ipnet.IP.To4() != nil {
|
|
||||||
res = append(res, ipnet.IP.To4())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start - start server
|
// Start - start server
|
||||||
func (s *V4Server) Start() error {
|
func (s *v4Server) Start() error {
|
||||||
if !s.conf.Enabled {
|
if !s.conf.Enabled {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -586,14 +551,14 @@ func (s *V4Server) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset - stop server
|
// Reset - stop server
|
||||||
func (s *V4Server) Reset() {
|
func (s *v4Server) Reset() {
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
s.leases = nil
|
s.leases = nil
|
||||||
s.leasesLock.Unlock()
|
s.leasesLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop - stop server
|
// Stop - stop server
|
||||||
func (s *V4Server) Stop() {
|
func (s *v4Server) Stop() {
|
||||||
if s.srv == nil {
|
if s.srv == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -605,9 +570,9 @@ func (s *V4Server) Stop() {
|
||||||
// now server.Serve() will return
|
// now server.Serve() will return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create DHCPv6 server
|
// Create DHCPv4 server
|
||||||
func v4Create(conf V4ServerConf) (*V4Server, error) {
|
func v4Create(conf V4ServerConf) (DHCPServer, error) {
|
||||||
s := &V4Server{}
|
s := &v4Server{}
|
||||||
s.conf = conf
|
s.conf = conf
|
||||||
|
|
||||||
if !conf.Enabled {
|
if !conf.Enabled {
|
||||||
|
|
45
dhcpd/v46_windows.go
Normal file
45
dhcpd/v46_windows.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package dhcpd
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
type winServer struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *winServer) ResetLeases(leases []*Lease) {
|
||||||
|
}
|
||||||
|
func (s *winServer) GetLeases(flags int) []Lease {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *winServer) GetLeasesRef() []*Lease {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *winServer) AddStaticLease(lease Lease) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *winServer) RemoveStaticLease(l Lease) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *winServer) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *winServer) WriteDiskConfig4(c *V4ServerConf) {
|
||||||
|
}
|
||||||
|
func (s *winServer) WriteDiskConfig6(c *V6ServerConf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *winServer) Start() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *winServer) Stop() {
|
||||||
|
}
|
||||||
|
func (s *winServer) Reset() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func v4Create(conf V4ServerConf) (DHCPServer, error) {
|
||||||
|
return &winServer{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func v6Create(conf V6ServerConf) (DHCPServer, error) {
|
||||||
|
return &winServer{}, nil
|
||||||
|
}
|
224
dhcpd/v4_test.go
Normal file
224
dhcpd/v4_test.go
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
package dhcpd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/insomniacslk/dhcp/dhcpv4"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func notify4(flags uint32) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestV4StaticLeaseAddRemove(t *testing.T) {
|
||||||
|
conf := V4ServerConf{
|
||||||
|
Enabled: true,
|
||||||
|
RangeStart: "192.168.10.100",
|
||||||
|
RangeEnd: "192.168.10.200",
|
||||||
|
GatewayIP: "192.168.10.1",
|
||||||
|
SubnetMask: "255.255.255.0",
|
||||||
|
notify: notify4,
|
||||||
|
}
|
||||||
|
s, err := v4Create(conf)
|
||||||
|
assert.True(t, err == nil)
|
||||||
|
|
||||||
|
ls := s.GetLeases(LeasesStatic)
|
||||||
|
assert.Equal(t, 0, len(ls))
|
||||||
|
|
||||||
|
// add static lease
|
||||||
|
l := Lease{}
|
||||||
|
l.IP = net.ParseIP("192.168.10.150").To4()
|
||||||
|
l.HWAddr, _ = net.ParseMAC("aa:aa:aa:aa:aa:aa")
|
||||||
|
assert.True(t, s.AddStaticLease(l) == nil)
|
||||||
|
|
||||||
|
// try to add the same static lease - fail
|
||||||
|
assert.True(t, s.AddStaticLease(l) != nil)
|
||||||
|
|
||||||
|
// check
|
||||||
|
ls = s.GetLeases(LeasesStatic)
|
||||||
|
assert.Equal(t, 1, len(ls))
|
||||||
|
assert.Equal(t, "192.168.10.150", ls[0].IP.String())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", ls[0].HWAddr.String())
|
||||||
|
assert.True(t, ls[0].Expiry.Unix() == leaseExpireStatic)
|
||||||
|
|
||||||
|
// try to remove static lease - fail
|
||||||
|
l.IP = net.ParseIP("192.168.10.110").To4()
|
||||||
|
l.HWAddr, _ = net.ParseMAC("aa:aa:aa:aa:aa:aa")
|
||||||
|
assert.True(t, s.RemoveStaticLease(l) != nil)
|
||||||
|
|
||||||
|
// remove static lease
|
||||||
|
l.IP = net.ParseIP("192.168.10.150").To4()
|
||||||
|
l.HWAddr, _ = net.ParseMAC("aa:aa:aa:aa:aa:aa")
|
||||||
|
assert.True(t, s.RemoveStaticLease(l) == nil)
|
||||||
|
|
||||||
|
// check
|
||||||
|
ls = s.GetLeases(LeasesStatic)
|
||||||
|
assert.Equal(t, 0, len(ls))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestV4StaticLeaseAddReplaceDynamic(t *testing.T) {
|
||||||
|
conf := V4ServerConf{
|
||||||
|
Enabled: true,
|
||||||
|
RangeStart: "192.168.10.100",
|
||||||
|
RangeEnd: "192.168.10.200",
|
||||||
|
GatewayIP: "192.168.10.1",
|
||||||
|
SubnetMask: "255.255.255.0",
|
||||||
|
notify: notify4,
|
||||||
|
}
|
||||||
|
s, err := v4Create(conf)
|
||||||
|
assert.True(t, err == nil)
|
||||||
|
|
||||||
|
// add dynamic lease
|
||||||
|
ld := Lease{}
|
||||||
|
ld.IP = net.ParseIP("192.168.10.150").To4()
|
||||||
|
ld.HWAddr, _ = net.ParseMAC("11:aa:aa:aa:aa:aa")
|
||||||
|
s.addLease(&ld)
|
||||||
|
|
||||||
|
// add dynamic lease
|
||||||
|
{
|
||||||
|
ld := Lease{}
|
||||||
|
ld.IP = net.ParseIP("192.168.10.151").To4()
|
||||||
|
ld.HWAddr, _ = net.ParseMAC("22:aa:aa:aa:aa:aa")
|
||||||
|
s.addLease(&ld)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add static lease with the same IP
|
||||||
|
l := Lease{}
|
||||||
|
l.IP = net.ParseIP("192.168.10.150").To4()
|
||||||
|
l.HWAddr, _ = net.ParseMAC("33:aa:aa:aa:aa:aa")
|
||||||
|
assert.True(t, s.AddStaticLease(l) == nil)
|
||||||
|
|
||||||
|
// add static lease with the same MAC
|
||||||
|
l = Lease{}
|
||||||
|
l.IP = net.ParseIP("192.168.10.152").To4()
|
||||||
|
l.HWAddr, _ = net.ParseMAC("22:aa:aa:aa:aa:aa")
|
||||||
|
assert.True(t, s.AddStaticLease(l) == nil)
|
||||||
|
|
||||||
|
// check
|
||||||
|
ls := s.GetLeases(LeasesStatic)
|
||||||
|
assert.Equal(t, 2, len(ls))
|
||||||
|
|
||||||
|
assert.Equal(t, "192.168.10.150", ls[0].IP.String())
|
||||||
|
assert.Equal(t, "33:aa:aa:aa:aa:aa", ls[0].HWAddr.String())
|
||||||
|
assert.True(t, ls[0].Expiry.Unix() == leaseExpireStatic)
|
||||||
|
|
||||||
|
assert.Equal(t, "192.168.10.152", ls[1].IP.String())
|
||||||
|
assert.Equal(t, "22:aa:aa:aa:aa:aa", ls[1].HWAddr.String())
|
||||||
|
assert.True(t, ls[1].Expiry.Unix() == leaseExpireStatic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestV4StaticLeaseGet(t *testing.T) {
|
||||||
|
conf := V4ServerConf{
|
||||||
|
Enabled: true,
|
||||||
|
RangeStart: "192.168.10.100",
|
||||||
|
RangeEnd: "192.168.10.200",
|
||||||
|
GatewayIP: "192.168.10.1",
|
||||||
|
SubnetMask: "255.255.255.0",
|
||||||
|
notify: notify4,
|
||||||
|
}
|
||||||
|
s, err := v4Create(conf)
|
||||||
|
assert.True(t, err == nil)
|
||||||
|
s.conf.dnsIPAddrs = []net.IP{net.ParseIP("192.168.10.1").To4()}
|
||||||
|
|
||||||
|
l := Lease{}
|
||||||
|
l.IP = net.ParseIP("192.168.10.150").To4()
|
||||||
|
l.HWAddr, _ = net.ParseMAC("aa:aa:aa:aa:aa:aa")
|
||||||
|
assert.True(t, s.AddStaticLease(l) == nil)
|
||||||
|
|
||||||
|
// "Discover"
|
||||||
|
mac, _ := net.ParseMAC("aa:aa:aa:aa:aa:aa")
|
||||||
|
req, _ := dhcpv4.NewDiscovery(mac)
|
||||||
|
resp, _ := dhcpv4.NewReplyFromRequest(req)
|
||||||
|
assert.Equal(t, 1, s.process(req, resp))
|
||||||
|
|
||||||
|
// check "Offer"
|
||||||
|
assert.Equal(t, dhcpv4.MessageTypeOffer, resp.MessageType())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", resp.ClientHWAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.150", resp.YourIPAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.Router()[0].String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.ServerIdentifier().String())
|
||||||
|
assert.Equal(t, "255.255.255.0", net.IP(resp.SubnetMask()).String())
|
||||||
|
assert.Equal(t, s.conf.leaseTime.Seconds(), resp.IPAddressLeaseTime(-1).Seconds())
|
||||||
|
|
||||||
|
// "Request"
|
||||||
|
req, _ = dhcpv4.NewRequestFromOffer(resp)
|
||||||
|
resp, _ = dhcpv4.NewReplyFromRequest(req)
|
||||||
|
assert.Equal(t, 1, s.process(req, resp))
|
||||||
|
|
||||||
|
// check "Ack"
|
||||||
|
assert.Equal(t, dhcpv4.MessageTypeAck, resp.MessageType())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", resp.ClientHWAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.150", resp.YourIPAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.Router()[0].String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.ServerIdentifier().String())
|
||||||
|
assert.Equal(t, "255.255.255.0", net.IP(resp.SubnetMask()).String())
|
||||||
|
assert.Equal(t, s.conf.leaseTime.Seconds(), resp.IPAddressLeaseTime(-1).Seconds())
|
||||||
|
|
||||||
|
dnsAddrs := resp.DNS()
|
||||||
|
assert.Equal(t, 1, len(dnsAddrs))
|
||||||
|
assert.Equal(t, "192.168.10.1", dnsAddrs[0].String())
|
||||||
|
|
||||||
|
// check lease
|
||||||
|
ls := s.GetLeases(LeasesStatic)
|
||||||
|
assert.Equal(t, 1, len(ls))
|
||||||
|
assert.Equal(t, "192.168.10.150", ls[0].IP.String())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", ls[0].HWAddr.String())
|
||||||
|
|
||||||
|
s.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestV4DynamicLeaseGet(t *testing.T) {
|
||||||
|
conf := V4ServerConf{
|
||||||
|
Enabled: true,
|
||||||
|
RangeStart: "192.168.10.100",
|
||||||
|
RangeEnd: "192.168.10.200",
|
||||||
|
GatewayIP: "192.168.10.1",
|
||||||
|
SubnetMask: "255.255.255.0",
|
||||||
|
notify: notify4,
|
||||||
|
}
|
||||||
|
s, err := v4Create(conf)
|
||||||
|
assert.True(t, err == nil)
|
||||||
|
s.conf.dnsIPAddrs = []net.IP{net.ParseIP("192.168.10.1").To4()}
|
||||||
|
|
||||||
|
// "Discover"
|
||||||
|
mac, _ := net.ParseMAC("aa:aa:aa:aa:aa:aa")
|
||||||
|
req, _ := dhcpv4.NewDiscovery(mac)
|
||||||
|
resp, _ := dhcpv4.NewReplyFromRequest(req)
|
||||||
|
assert.Equal(t, 1, s.process(req, resp))
|
||||||
|
|
||||||
|
// check "Offer"
|
||||||
|
assert.Equal(t, dhcpv4.MessageTypeOffer, resp.MessageType())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", resp.ClientHWAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.100", resp.YourIPAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.Router()[0].String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.ServerIdentifier().String())
|
||||||
|
assert.Equal(t, "255.255.255.0", net.IP(resp.SubnetMask()).String())
|
||||||
|
assert.Equal(t, s.conf.leaseTime.Seconds(), resp.IPAddressLeaseTime(-1).Seconds())
|
||||||
|
|
||||||
|
// "Request"
|
||||||
|
req, _ = dhcpv4.NewRequestFromOffer(resp)
|
||||||
|
resp, _ = dhcpv4.NewReplyFromRequest(req)
|
||||||
|
assert.Equal(t, 1, s.process(req, resp))
|
||||||
|
|
||||||
|
// check "Ack"
|
||||||
|
assert.Equal(t, dhcpv4.MessageTypeAck, resp.MessageType())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", resp.ClientHWAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.100", resp.YourIPAddr.String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.Router()[0].String())
|
||||||
|
assert.Equal(t, "192.168.10.1", resp.ServerIdentifier().String())
|
||||||
|
assert.Equal(t, "255.255.255.0", net.IP(resp.SubnetMask()).String())
|
||||||
|
assert.Equal(t, s.conf.leaseTime.Seconds(), resp.IPAddressLeaseTime(-1).Seconds())
|
||||||
|
|
||||||
|
dnsAddrs := resp.DNS()
|
||||||
|
assert.Equal(t, 1, len(dnsAddrs))
|
||||||
|
assert.Equal(t, "192.168.10.1", dnsAddrs[0].String())
|
||||||
|
|
||||||
|
// check lease
|
||||||
|
ls := s.GetLeases(LeasesDynamic)
|
||||||
|
assert.Equal(t, 1, len(ls))
|
||||||
|
assert.Equal(t, "192.168.10.100", ls[0].IP.String())
|
||||||
|
assert.Equal(t, "aa:aa:aa:aa:aa:aa", ls[0].HWAddr.String())
|
||||||
|
|
||||||
|
s.Stop()
|
||||||
|
}
|
82
dhcpd/v6.go
82
dhcpd/v6.go
|
@ -1,3 +1,5 @@
|
||||||
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
package dhcpd
|
package dhcpd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -15,38 +17,28 @@ import (
|
||||||
|
|
||||||
const valueIAID = "ADGH" // value for IANA.ID
|
const valueIAID = "ADGH" // value for IANA.ID
|
||||||
|
|
||||||
// V6Server - DHCPv6 server
|
// v6Server - DHCPv6 server
|
||||||
type V6Server struct {
|
type v6Server struct {
|
||||||
srv *server6.Server
|
srv *server6.Server
|
||||||
leasesLock sync.Mutex
|
leasesLock sync.Mutex
|
||||||
leases []*Lease
|
leases []*Lease
|
||||||
ipAddrs [256]byte
|
ipAddrs [256]byte
|
||||||
|
sid dhcpv6.Duid
|
||||||
|
|
||||||
conf V6ServerConf
|
conf V6ServerConf
|
||||||
}
|
}
|
||||||
|
|
||||||
// V6ServerConf - server configuration
|
// WriteDiskConfig4 - write configuration
|
||||||
type V6ServerConf struct {
|
func (s *v6Server) WriteDiskConfig4(c *V4ServerConf) {
|
||||||
Enabled bool `yaml:"enabled"`
|
|
||||||
InterfaceName string `yaml:"interface_name"`
|
|
||||||
RangeStart string `yaml:"range_start"`
|
|
||||||
LeaseDuration uint32 `yaml:"lease_duration"` // in seconds
|
|
||||||
|
|
||||||
ipStart net.IP
|
|
||||||
leaseTime time.Duration
|
|
||||||
dnsIPAddrs []net.IP // IPv6 addresses to return to DHCP clients as DNS server addresses
|
|
||||||
sid dhcpv6.Duid
|
|
||||||
|
|
||||||
notify func(uint32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteDiskConfig - write configuration
|
// WriteDiskConfig6 - write configuration
|
||||||
func (s *V6Server) WriteDiskConfig(c *V6ServerConf) {
|
func (s *v6Server) WriteDiskConfig6(c *V6ServerConf) {
|
||||||
*c = s.conf
|
*c = s.conf
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetLeases - reset leases
|
// ResetLeases - reset leases
|
||||||
func (s *V6Server) ResetLeases(ll []*Lease) {
|
func (s *v6Server) ResetLeases(ll []*Lease) {
|
||||||
s.leases = nil
|
s.leases = nil
|
||||||
for _, l := range ll {
|
for _, l := range ll {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -55,7 +47,7 @@ func (s *V6Server) ResetLeases(ll []*Lease) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLeases - get current leases
|
// GetLeases - get current leases
|
||||||
func (s *V6Server) GetLeases(flags int) []Lease {
|
func (s *v6Server) GetLeases(flags int) []Lease {
|
||||||
var result []Lease
|
var result []Lease
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
for _, lease := range s.leases {
|
for _, lease := range s.leases {
|
||||||
|
@ -76,12 +68,12 @@ func (s *V6Server) GetLeases(flags int) []Lease {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLeasesRef - get leases
|
// GetLeasesRef - get leases
|
||||||
func (s *V6Server) GetLeasesRef() []*Lease {
|
func (s *v6Server) GetLeasesRef() []*Lease {
|
||||||
return s.leases
|
return s.leases
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases
|
// FindMACbyIP - find a MAC address by IP address in the currently active DHCP leases
|
||||||
func (s *V6Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
func (s *v6Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
|
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
|
@ -104,7 +96,7 @@ func (s *V6Server) FindMACbyIP(ip net.IP) net.HardwareAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove (swap) lease by index
|
// Remove (swap) lease by index
|
||||||
func (s *V6Server) leaseRemoveSwapByIndex(i int) {
|
func (s *v6Server) leaseRemoveSwapByIndex(i int) {
|
||||||
s.ipAddrs[s.leases[i].IP[15]] = 0
|
s.ipAddrs[s.leases[i].IP[15]] = 0
|
||||||
log.Debug("DHCPv6: removed lease %s", s.leases[i].HWAddr)
|
log.Debug("DHCPv6: removed lease %s", s.leases[i].HWAddr)
|
||||||
|
|
||||||
|
@ -117,7 +109,7 @@ func (s *V6Server) leaseRemoveSwapByIndex(i int) {
|
||||||
|
|
||||||
// Remove a dynamic lease with the same properties
|
// Remove a dynamic lease with the same properties
|
||||||
// Return error if a static lease is found
|
// Return error if a static lease is found
|
||||||
func (s *V6Server) rmDynamicLease(lease Lease) error {
|
func (s *v6Server) rmDynamicLease(lease Lease) error {
|
||||||
for i := 0; i < len(s.leases); i++ {
|
for i := 0; i < len(s.leases); i++ {
|
||||||
l := s.leases[i]
|
l := s.leases[i]
|
||||||
|
|
||||||
|
@ -144,7 +136,7 @@ func (s *V6Server) rmDynamicLease(lease Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddStaticLease - add a static lease
|
// AddStaticLease - add a static lease
|
||||||
func (s *V6Server) AddStaticLease(l Lease) error {
|
func (s *v6Server) AddStaticLease(l Lease) error {
|
||||||
if len(l.IP) != 16 {
|
if len(l.IP) != 16 {
|
||||||
return fmt.Errorf("invalid IP")
|
return fmt.Errorf("invalid IP")
|
||||||
}
|
}
|
||||||
|
@ -169,7 +161,7 @@ func (s *V6Server) AddStaticLease(l Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveStaticLease - remove a static lease
|
// RemoveStaticLease - remove a static lease
|
||||||
func (s *V6Server) RemoveStaticLease(l Lease) error {
|
func (s *v6Server) RemoveStaticLease(l Lease) error {
|
||||||
if len(l.IP) != 16 {
|
if len(l.IP) != 16 {
|
||||||
return fmt.Errorf("invalid IP")
|
return fmt.Errorf("invalid IP")
|
||||||
}
|
}
|
||||||
|
@ -190,14 +182,14 @@ func (s *V6Server) RemoveStaticLease(l Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a lease
|
// Add a lease
|
||||||
func (s *V6Server) addLease(l *Lease) {
|
func (s *v6Server) addLease(l *Lease) {
|
||||||
s.leases = append(s.leases, l)
|
s.leases = append(s.leases, l)
|
||||||
s.ipAddrs[l.IP[15]] = 1
|
s.ipAddrs[l.IP[15]] = 1
|
||||||
log.Debug("DHCPv6: added lease %s <-> %s", l.IP, l.HWAddr)
|
log.Debug("DHCPv6: added lease %s <-> %s", l.IP, l.HWAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a lease with the same properties
|
// Remove a lease with the same properties
|
||||||
func (s *V6Server) rmLease(lease Lease) error {
|
func (s *v6Server) rmLease(lease Lease) error {
|
||||||
for i, l := range s.leases {
|
for i, l := range s.leases {
|
||||||
if net.IP.Equal(l.IP, lease.IP) {
|
if net.IP.Equal(l.IP, lease.IP) {
|
||||||
|
|
||||||
|
@ -215,7 +207,7 @@ func (s *V6Server) rmLease(lease Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find lease by MAC
|
// Find lease by MAC
|
||||||
func (s *V6Server) findLease(mac net.HardwareAddr) *Lease {
|
func (s *v6Server) findLease(mac net.HardwareAddr) *Lease {
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
defer s.leasesLock.Unlock()
|
defer s.leasesLock.Unlock()
|
||||||
|
|
||||||
|
@ -228,7 +220,7 @@ func (s *V6Server) findLease(mac net.HardwareAddr) *Lease {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find an expired lease and return its index or -1
|
// Find an expired lease and return its index or -1
|
||||||
func (s *V6Server) findExpiredLease() int {
|
func (s *v6Server) findExpiredLease() int {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
for i, lease := range s.leases {
|
for i, lease := range s.leases {
|
||||||
if lease.Expiry.Unix() != leaseExpireStatic &&
|
if lease.Expiry.Unix() != leaseExpireStatic &&
|
||||||
|
@ -240,7 +232,7 @@ func (s *V6Server) findExpiredLease() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get next free IP
|
// Get next free IP
|
||||||
func (s *V6Server) findFreeIP() net.IP {
|
func (s *v6Server) findFreeIP() net.IP {
|
||||||
for i := s.conf.ipStart[15]; ; i++ {
|
for i := s.conf.ipStart[15]; ; i++ {
|
||||||
if s.ipAddrs[i] == 0 {
|
if s.ipAddrs[i] == 0 {
|
||||||
ip := make([]byte, 16)
|
ip := make([]byte, 16)
|
||||||
|
@ -256,7 +248,7 @@ func (s *V6Server) findFreeIP() net.IP {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve lease for MAC
|
// Reserve lease for MAC
|
||||||
func (s *V6Server) reserveLease(mac net.HardwareAddr) *Lease {
|
func (s *v6Server) reserveLease(mac net.HardwareAddr) *Lease {
|
||||||
l := Lease{}
|
l := Lease{}
|
||||||
l.HWAddr = make([]byte, 6)
|
l.HWAddr = make([]byte, 6)
|
||||||
copy(l.HWAddr, mac)
|
copy(l.HWAddr, mac)
|
||||||
|
@ -280,7 +272,7 @@ func (s *V6Server) reserveLease(mac net.HardwareAddr) *Lease {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Client ID
|
// Check Client ID
|
||||||
func (s *V6Server) checkCID(msg *dhcpv6.Message) error {
|
func (s *v6Server) checkCID(msg *dhcpv6.Message) error {
|
||||||
if msg.Options.ClientID() == nil {
|
if msg.Options.ClientID() == nil {
|
||||||
return fmt.Errorf("DHCPv6: no ClientID option in request")
|
return fmt.Errorf("DHCPv6: no ClientID option in request")
|
||||||
}
|
}
|
||||||
|
@ -288,7 +280,7 @@ func (s *V6Server) checkCID(msg *dhcpv6.Message) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check ServerID policy
|
// Check ServerID policy
|
||||||
func (s *V6Server) checkSID(msg *dhcpv6.Message) error {
|
func (s *v6Server) checkSID(msg *dhcpv6.Message) error {
|
||||||
sid := msg.Options.ServerID()
|
sid := msg.Options.ServerID()
|
||||||
|
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
|
@ -308,7 +300,7 @@ func (s *V6Server) checkSID(msg *dhcpv6.Message) error {
|
||||||
if sid == nil {
|
if sid == nil {
|
||||||
return fmt.Errorf("DHCPv6: drop packet: no ServerID option in message %s", msg.Type().String())
|
return fmt.Errorf("DHCPv6: drop packet: no ServerID option in message %s", msg.Type().String())
|
||||||
}
|
}
|
||||||
if !sid.Equal(s.conf.sid) {
|
if !sid.Equal(s.sid) {
|
||||||
return fmt.Errorf("DHCPv6: drop packet: mismatched ServerID option in message %s: %s",
|
return fmt.Errorf("DHCPv6: drop packet: mismatched ServerID option in message %s: %s",
|
||||||
msg.Type().String(), sid.String())
|
msg.Type().String(), sid.String())
|
||||||
}
|
}
|
||||||
|
@ -319,7 +311,7 @@ func (s *V6Server) checkSID(msg *dhcpv6.Message) error {
|
||||||
|
|
||||||
// . IAID must be equal to this server's ID
|
// . IAID must be equal to this server's ID
|
||||||
// . IAAddress must be equal to the lease's IP
|
// . IAAddress must be equal to the lease's IP
|
||||||
func (s *V6Server) checkIA(msg *dhcpv6.Message, lease *Lease) error {
|
func (s *v6Server) checkIA(msg *dhcpv6.Message, lease *Lease) error {
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
case dhcpv6.MessageTypeRequest,
|
case dhcpv6.MessageTypeRequest,
|
||||||
dhcpv6.MessageTypeConfirm,
|
dhcpv6.MessageTypeConfirm,
|
||||||
|
@ -348,7 +340,7 @@ func (s *V6Server) checkIA(msg *dhcpv6.Message, lease *Lease) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store lease in DB (if necessary) and return lease life time
|
// Store lease in DB (if necessary) and return lease life time
|
||||||
func (s *V6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration {
|
func (s *v6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration {
|
||||||
lifetime := s.conf.leaseTime
|
lifetime := s.conf.leaseTime
|
||||||
|
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
|
@ -376,7 +368,7 @@ func (s *V6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a lease associated with MAC and prepare response
|
// Find a lease associated with MAC and prepare response
|
||||||
func (s *V6Server) process(msg *dhcpv6.Message, req dhcpv6.DHCPv6, resp dhcpv6.DHCPv6) bool {
|
func (s *v6Server) process(msg *dhcpv6.Message, req dhcpv6.DHCPv6, resp dhcpv6.DHCPv6) bool {
|
||||||
switch msg.Type() {
|
switch msg.Type() {
|
||||||
case dhcpv6.MessageTypeSolicit,
|
case dhcpv6.MessageTypeSolicit,
|
||||||
dhcpv6.MessageTypeRequest,
|
dhcpv6.MessageTypeRequest,
|
||||||
|
@ -452,7 +444,7 @@ func (s *V6Server) process(msg *dhcpv6.Message, req dhcpv6.DHCPv6, resp dhcpv6.D
|
||||||
//
|
//
|
||||||
// 3.
|
// 3.
|
||||||
// fe80::* --(Release + ClientID+ServerID+IANA(IAAddress))-> ff02::1:2
|
// fe80::* --(Release + ClientID+ServerID+IANA(IAAddress))-> ff02::1:2
|
||||||
func (s *V6Server) packetHandler(conn net.PacketConn, peer net.Addr, req dhcpv6.DHCPv6) {
|
func (s *v6Server) packetHandler(conn net.PacketConn, peer net.Addr, req dhcpv6.DHCPv6) {
|
||||||
msg, err := req.GetInnerMessage()
|
msg, err := req.GetInnerMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("DHCPv6: %s", err)
|
log.Error("DHCPv6: %s", err)
|
||||||
|
@ -501,7 +493,7 @@ func (s *V6Server) packetHandler(conn net.PacketConn, peer net.Addr, req dhcpv6.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.AddOption(dhcpv6.OptServerID(s.conf.sid))
|
resp.AddOption(dhcpv6.OptServerID(s.sid))
|
||||||
|
|
||||||
_ = s.process(msg, req, resp)
|
_ = s.process(msg, req, resp)
|
||||||
|
|
||||||
|
@ -535,7 +527,7 @@ func getIfaceIPv6(iface net.Interface) []net.IP {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start - start server
|
// Start - start server
|
||||||
func (s *V6Server) Start() error {
|
func (s *v6Server) Start() error {
|
||||||
if !s.conf.Enabled {
|
if !s.conf.Enabled {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -558,7 +550,7 @@ func (s *V6Server) Start() error {
|
||||||
if len(iface.HardwareAddr) != 6 {
|
if len(iface.HardwareAddr) != 6 {
|
||||||
return fmt.Errorf("DHCPv6: invalid MAC %s", iface.HardwareAddr)
|
return fmt.Errorf("DHCPv6: invalid MAC %s", iface.HardwareAddr)
|
||||||
}
|
}
|
||||||
s.conf.sid = dhcpv6.Duid{
|
s.sid = dhcpv6.Duid{
|
||||||
Type: dhcpv6.DUID_LLT,
|
Type: dhcpv6.DUID_LLT,
|
||||||
HwType: iana.HWTypeEthernet,
|
HwType: iana.HWTypeEthernet,
|
||||||
LinkLayerAddr: iface.HardwareAddr,
|
LinkLayerAddr: iface.HardwareAddr,
|
||||||
|
@ -581,14 +573,14 @@ func (s *V6Server) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset - stop server
|
// Reset - stop server
|
||||||
func (s *V6Server) Reset() {
|
func (s *v6Server) Reset() {
|
||||||
s.leasesLock.Lock()
|
s.leasesLock.Lock()
|
||||||
s.leases = nil
|
s.leases = nil
|
||||||
s.leasesLock.Unlock()
|
s.leasesLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop - stop server
|
// Stop - stop server
|
||||||
func (s *V6Server) Stop() {
|
func (s *v6Server) Stop() {
|
||||||
if s.srv == nil {
|
if s.srv == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -601,8 +593,8 @@ func (s *V6Server) Stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create DHCPv6 server
|
// Create DHCPv6 server
|
||||||
func v6Create(conf V6ServerConf) (*V6Server, error) {
|
func v6Create(conf V6ServerConf) (DHCPServer, error) {
|
||||||
s := &V6Server{}
|
s := &v6Server{}
|
||||||
s.conf = conf
|
s.conf = conf
|
||||||
|
|
||||||
if !conf.Enabled {
|
if !conf.Enabled {
|
||||||
|
|
|
@ -84,6 +84,7 @@ type clientsContainer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes clients container
|
// Init initializes clients container
|
||||||
|
// dhcpServer: optional
|
||||||
// Note: this function must be called only once
|
// Note: this function must be called only once
|
||||||
func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.Server, autoHosts *util.AutoHosts) {
|
func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.Server, autoHosts *util.AutoHosts) {
|
||||||
if clients.list != nil {
|
if clients.list != nil {
|
||||||
|
@ -104,7 +105,9 @@ func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.
|
||||||
|
|
||||||
if !clients.testing {
|
if !clients.testing {
|
||||||
clients.addFromDHCP()
|
clients.addFromDHCP()
|
||||||
clients.dhcpServer.SetOnLeaseChanged(clients.onDHCPLeaseChanged)
|
if clients.dhcpServer != nil {
|
||||||
|
clients.dhcpServer.SetOnLeaseChanged(clients.onDHCPLeaseChanged)
|
||||||
|
}
|
||||||
clients.autoHosts.SetOnChanged(clients.onHostsChanged)
|
clients.autoHosts.SetOnChanged(clients.onHostsChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue