mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2025-03-14 14:38:29 +03:00
wip
This commit is contained in:
parent
cdb00a5db7
commit
2a9b87c672
6 changed files with 291 additions and 208 deletions
|
@ -97,8 +97,8 @@ func (s *Server) CheckConfig(config ServerConfig) error {
|
|||
// Create - create object
|
||||
func Create(config ServerConfig) *Server {
|
||||
s := Server{}
|
||||
s.conf.Conf4.notify = s.onNotify
|
||||
s.conf.Conf6.notify = s.onNotify
|
||||
config.Conf4.notify = s.onNotify
|
||||
config.Conf6.notify = s.onNotify
|
||||
s.conf.DBFilePath = filepath.Join(config.WorkDir, dbFilename)
|
||||
|
||||
if !webHandlersRegistered && s.conf.HTTPRegister != nil {
|
||||
|
@ -135,11 +135,6 @@ func (s *Server) onNotify(flags uint32) {
|
|||
s.notify(int(flags))
|
||||
}
|
||||
|
||||
// Init checks the configuration and initializes the server
|
||||
func (s *Server) Init(config ServerConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetOnLeaseChanged - set callback
|
||||
func (s *Server) SetOnLeaseChanged(onLeaseChanged onLeaseChangedT) {
|
||||
s.onLeaseChanged = onLeaseChanged
|
||||
|
|
442
dhcpd/v4.go
442
dhcpd/v4.go
|
@ -2,6 +2,7 @@ package dhcpd
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
@ -18,8 +19,7 @@ type V4Server struct {
|
|||
srv *server4.Server
|
||||
leasesLock sync.Mutex
|
||||
leases []*Lease
|
||||
// IP address pool -- if entry is in the pool, then it's attached to a lease
|
||||
IPpool map[[4]byte]net.HardwareAddr
|
||||
ipAddrs [256]byte
|
||||
|
||||
conf V4ServerConf
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ type V4ServerConf struct {
|
|||
ICMPTimeout uint32 `json:"icmp_timeout_msec" yaml:"icmp_timeout_msec"`
|
||||
|
||||
ipStart net.IP
|
||||
ipStop 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
|
||||
|
@ -53,30 +53,28 @@ func (s *V4Server) WriteDiskConfig(c *V4ServerConf) {
|
|||
*c = s.conf
|
||||
}
|
||||
|
||||
func ipInRange(start, stop, ip net.IP) bool {
|
||||
if len(start) != len(stop) ||
|
||||
len(start) != len(ip) {
|
||||
return false
|
||||
}
|
||||
// return dhcp4.IPInRange(start, stop, ip)
|
||||
return false
|
||||
// Return TRUE if IP address is within range [start..stop]
|
||||
func ipInRange(start net.IP, stop net.IP, ip net.IP) bool {
|
||||
from := binary.BigEndian.Uint32(start)
|
||||
to := binary.BigEndian.Uint32(stop)
|
||||
check := binary.BigEndian.Uint32(ip)
|
||||
return from <= check && check <= to
|
||||
}
|
||||
|
||||
// ResetLeases - reset leases
|
||||
func (s *V4Server) ResetLeases(ll []*Lease) {
|
||||
func (s *V4Server) ResetLeases(leases []*Lease) {
|
||||
s.leases = nil
|
||||
s.IPpool = make(map[[4]byte]net.HardwareAddr)
|
||||
for _, l := range ll {
|
||||
|
||||
for _, l := range leases {
|
||||
|
||||
if l.Expiry.Unix() != leaseExpireStatic &&
|
||||
!ipInRange(s.conf.ipStart, s.conf.ipStop, l.IP) {
|
||||
!ipInRange(s.conf.ipStart, s.conf.ipEnd, l.IP) {
|
||||
|
||||
log.Tracef("DHCPv4: skipping a lease with IP %v: not within current IP range", l.IP)
|
||||
log.Debug("DHCPv4: skipping a lease with IP %v: not within current IP range", l.IP)
|
||||
continue
|
||||
}
|
||||
|
||||
s.leases = append(s.leases, l)
|
||||
s.reserveIP(l.IP, l.HWAddr)
|
||||
s.addLease(l)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,6 +82,7 @@ func (s *V4Server) ResetLeases(ll []*Lease) {
|
|||
func (s *V4Server) GetLeases(flags int) []Lease {
|
||||
var result []Lease
|
||||
now := time.Now().Unix()
|
||||
|
||||
s.leasesLock.Lock()
|
||||
for _, lease := range s.leases {
|
||||
if ((flags&LeasesDynamic) != 0 && lease.Expiry.Unix() > now) ||
|
||||
|
@ -92,6 +91,7 @@ func (s *V4Server) GetLeases(flags int) []Lease {
|
|||
}
|
||||
}
|
||||
s.leasesLock.Unlock()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -118,118 +118,99 @@ func (s *V4Server) FindMACbyIP4(ip net.IP) net.HardwareAddr {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *V4Server) reserveIP(ip net.IP, hwaddr net.HardwareAddr) {
|
||||
rawIP := []byte(ip)
|
||||
IP4 := [4]byte{rawIP[0], rawIP[1], rawIP[2], rawIP[3]}
|
||||
s.IPpool[IP4] = hwaddr
|
||||
}
|
||||
|
||||
func (s *V4Server) unreserveIP(ip net.IP) {
|
||||
rawIP := []byte(ip)
|
||||
IP4 := [4]byte{rawIP[0], rawIP[1], rawIP[2], rawIP[3]}
|
||||
delete(s.IPpool, IP4)
|
||||
}
|
||||
|
||||
func (s *V4Server) findReservedHWaddr(ip net.IP) net.HardwareAddr {
|
||||
rawIP := []byte(ip)
|
||||
IP4 := [4]byte{rawIP[0], rawIP[1], rawIP[2], rawIP[3]}
|
||||
return s.IPpool[IP4]
|
||||
}
|
||||
|
||||
// Add the specified IP to the black list for a time period
|
||||
func (s *V4Server) blacklistLease(lease *Lease) {
|
||||
hw := make(net.HardwareAddr, 6)
|
||||
s.leasesLock.Lock()
|
||||
s.reserveIP(lease.IP, hw)
|
||||
lease.HWAddr = hw
|
||||
lease.Hostname = ""
|
||||
lease.Expiry = time.Now().Add(s.conf.leaseTime)
|
||||
s.conf.notify(LeaseChangedDBStore)
|
||||
s.leasesLock.Unlock()
|
||||
s.conf.notify(LeaseChangedBlacklisted)
|
||||
}
|
||||
|
||||
// Remove a dynamic lease by IP address
|
||||
func (s *V4Server) rmDynamicLeaseWithIP(ip net.IP) error {
|
||||
var newLeases []*Lease
|
||||
for _, lease := range s.leases {
|
||||
if net.IP.Equal(lease.IP.To4(), ip) {
|
||||
if lease.Expiry.Unix() == leaseExpireStatic {
|
||||
return fmt.Errorf("static lease with the same IP already exists")
|
||||
}
|
||||
continue
|
||||
}
|
||||
newLeases = append(newLeases, lease)
|
||||
// Remove (swap) lease by index
|
||||
func (s *V4Server) leaseRemoveSwapByIndex(i int) {
|
||||
s.ipAddrs[s.leases[i].IP[3]] = 0
|
||||
log.Debug("DHCPv4: removed lease %s", s.leases[i].HWAddr)
|
||||
|
||||
n := len(s.leases)
|
||||
if i != n-1 {
|
||||
s.leases[i] = s.leases[n-1] // swap with the last element
|
||||
}
|
||||
s.leases = s.leases[:n-1]
|
||||
}
|
||||
|
||||
// Remove a dynamic lease with the same properties
|
||||
// Return error if a static lease is found
|
||||
func (s *V4Server) rmDynamicLease(lease Lease) error {
|
||||
for i := 0; i < len(s.leases); i++ {
|
||||
l := s.leases[i]
|
||||
|
||||
if bytes.Equal(l.HWAddr, lease.HWAddr) {
|
||||
|
||||
if l.Expiry.Unix() == leaseExpireStatic {
|
||||
return fmt.Errorf("static lease already exists")
|
||||
}
|
||||
|
||||
s.leaseRemoveSwapByIndex(i)
|
||||
l = s.leases[i]
|
||||
}
|
||||
|
||||
if bytes.Equal(l.IP, lease.IP) {
|
||||
|
||||
if l.Expiry.Unix() == leaseExpireStatic {
|
||||
return fmt.Errorf("static lease already exists")
|
||||
}
|
||||
|
||||
s.leaseRemoveSwapByIndex(i)
|
||||
}
|
||||
}
|
||||
s.leases = newLeases
|
||||
s.unreserveIP(ip)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove a dynamic lease by IP address
|
||||
func (s *V4Server) rmDynamicLeaseWithMAC(mac net.HardwareAddr) error {
|
||||
var newLeases []*Lease
|
||||
for _, lease := range s.leases {
|
||||
if bytes.Equal(lease.HWAddr, mac) {
|
||||
if lease.Expiry.Unix() == leaseExpireStatic {
|
||||
return fmt.Errorf("static lease with the same IP already exists")
|
||||
}
|
||||
s.unreserveIP(lease.IP)
|
||||
continue
|
||||
}
|
||||
newLeases = append(newLeases, lease)
|
||||
}
|
||||
s.leases = newLeases
|
||||
return nil
|
||||
// Add a lease
|
||||
func (s *V4Server) addLease(l *Lease) {
|
||||
s.leases = append(s.leases, l)
|
||||
s.ipAddrs[l.IP[3]] = 1
|
||||
log.Debug("DHCPv4: added lease %s <-> %s", l.IP, l.HWAddr)
|
||||
}
|
||||
|
||||
// Remove a lease
|
||||
func (s *V4Server) rmLease(l Lease) error {
|
||||
var newLeases []*Lease
|
||||
for _, lease := range s.leases {
|
||||
if net.IP.Equal(lease.IP.To4(), l.IP) {
|
||||
if !bytes.Equal(lease.HWAddr, l.HWAddr) ||
|
||||
lease.Hostname != l.Hostname {
|
||||
// Remove a lease with the same properies
|
||||
func (s *V4Server) rmLease(lease Lease) error {
|
||||
for i, l := range s.leases {
|
||||
if bytes.Equal(l.IP, lease.IP) {
|
||||
|
||||
if !bytes.Equal(l.HWAddr, lease.HWAddr) ||
|
||||
l.Hostname != lease.Hostname {
|
||||
|
||||
return fmt.Errorf("Lease not found")
|
||||
}
|
||||
continue
|
||||
|
||||
s.leaseRemoveSwapByIndex(i)
|
||||
return nil
|
||||
}
|
||||
newLeases = append(newLeases, lease)
|
||||
}
|
||||
s.leases = newLeases
|
||||
s.unreserveIP(l.IP)
|
||||
return nil
|
||||
return fmt.Errorf("lease not found")
|
||||
}
|
||||
|
||||
// AddStaticLease adds a static lease (thread-safe)
|
||||
func (s *V4Server) AddStaticLease(l Lease) error {
|
||||
if len(l.IP) != 4 {
|
||||
func (s *V4Server) AddStaticLease(lease Lease) error {
|
||||
if len(lease.IP) != 4 {
|
||||
return fmt.Errorf("invalid IP")
|
||||
}
|
||||
if len(l.HWAddr) != 6 {
|
||||
if len(lease.HWAddr) != 6 {
|
||||
return fmt.Errorf("invalid MAC")
|
||||
}
|
||||
l.Expiry = time.Unix(leaseExpireStatic, 0)
|
||||
lease.Expiry = time.Unix(leaseExpireStatic, 0)
|
||||
|
||||
s.leasesLock.Lock()
|
||||
|
||||
if s.findReservedHWaddr(l.IP) != nil {
|
||||
err := s.rmDynamicLeaseWithIP(l.IP)
|
||||
if err != nil {
|
||||
s.leasesLock.Unlock()
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err := s.rmDynamicLeaseWithMAC(l.HWAddr)
|
||||
if err != nil {
|
||||
s.leasesLock.Unlock()
|
||||
return err
|
||||
}
|
||||
err := s.rmDynamicLease(lease)
|
||||
if err != nil {
|
||||
s.leasesLock.Unlock()
|
||||
return err
|
||||
}
|
||||
s.leases = append(s.leases, &l)
|
||||
s.reserveIP(l.IP, l.HWAddr)
|
||||
s.addLease(&lease)
|
||||
s.conf.notify(LeaseChangedDBStore)
|
||||
s.leasesLock.Unlock()
|
||||
|
||||
s.conf.notify(LeaseChangedAddedStatic)
|
||||
return nil
|
||||
}
|
||||
|
@ -244,12 +225,6 @@ func (s *V4Server) RemoveStaticLease(l Lease) error {
|
|||
}
|
||||
|
||||
s.leasesLock.Lock()
|
||||
|
||||
if s.findReservedHWaddr(l.IP) == nil {
|
||||
s.leasesLock.Unlock()
|
||||
return fmt.Errorf("lease not found")
|
||||
}
|
||||
|
||||
err := s.rmLease(l)
|
||||
if err != nil {
|
||||
s.leasesLock.Unlock()
|
||||
|
@ -257,6 +232,7 @@ func (s *V4Server) RemoveStaticLease(l Lease) error {
|
|||
}
|
||||
s.conf.notify(LeaseChangedDBStore)
|
||||
s.leasesLock.Unlock()
|
||||
|
||||
s.conf.notify(LeaseChangedRemovedStatic)
|
||||
return nil
|
||||
}
|
||||
|
@ -280,85 +256,204 @@ func (s *V4Server) addrAvailable(target net.IP) bool {
|
|||
pinger.Count = 1
|
||||
reply := false
|
||||
pinger.OnRecv = func(pkt *ping.Packet) {
|
||||
// log.Tracef("Received ICMP Reply from %v", target)
|
||||
reply = true
|
||||
}
|
||||
log.Tracef("Sending ICMP Echo to %v", target)
|
||||
log.Debug("DHCPv4: Sending ICMP Echo to %v", target)
|
||||
pinger.Run()
|
||||
|
||||
if reply {
|
||||
log.Info("DHCP: IP conflict: %v is already used by another device", target)
|
||||
log.Info("DHCPv4: IP conflict: %v is already used by another device", target)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Tracef("ICMP procedure is complete: %v", target)
|
||||
log.Debug("DHCPv4: ICMP procedure is complete: %v", target)
|
||||
return true
|
||||
}
|
||||
|
||||
// Find lease by MAC
|
||||
func (s *V4Server) findLease(mac net.HardwareAddr) *Lease {
|
||||
for i := range s.leases {
|
||||
if bytes.Equal(mac, s.leases[i].HWAddr) {
|
||||
return s.leases[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get next free IP
|
||||
func (s *V4Server) findFreeIP() net.IP {
|
||||
for i := s.conf.ipStart[3]; i != s.conf.ipEnd[3]; i++ {
|
||||
if s.ipAddrs[i] == 0 {
|
||||
ip := make([]byte, 4)
|
||||
copy(ip, s.conf.ipStart)
|
||||
ip[3] = i
|
||||
return ip
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find an expired lease and return its index or -1
|
||||
func (s *V4Server) findExpiredLease() int {
|
||||
now := time.Now().Unix()
|
||||
for i, lease := range s.leases {
|
||||
if lease.Expiry.Unix() != leaseExpireStatic &&
|
||||
lease.Expiry.Unix() <= now {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// Reserve lease for MAC
|
||||
func (s *V4Server) reserveLease(mac net.HardwareAddr) *Lease {
|
||||
return nil
|
||||
}
|
||||
l := Lease{}
|
||||
l.HWAddr = make([]byte, 6)
|
||||
copy(l.HWAddr, mac)
|
||||
|
||||
func (s *V4Server) commitLease(req *dhcpv4.DHCPv4, lease *Lease) time.Duration {
|
||||
return 0
|
||||
}
|
||||
l.IP = s.findFreeIP()
|
||||
if l.IP == nil {
|
||||
i := s.findExpiredLease()
|
||||
if i < 0 {
|
||||
return nil
|
||||
}
|
||||
copy(s.leases[i].HWAddr, mac)
|
||||
return s.leases[i]
|
||||
}
|
||||
|
||||
func (s *V4Server) checkIA(req *dhcpv4.DHCPv4, lease *Lease) error {
|
||||
// req.GetOneOption(dhcpv4.OptionServerIdentifier)
|
||||
return nil
|
||||
s.addLease(&l)
|
||||
return &l
|
||||
}
|
||||
|
||||
// Find a lease associated with MAC and prepare response
|
||||
func (s *V4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) bool {
|
||||
func (s *V4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
|
||||
|
||||
var lease *Lease
|
||||
|
||||
mac := req.ClientHWAddr
|
||||
if len(mac) != 6 {
|
||||
log.Debug("DHCPv4: Invalid ClientHWAddr")
|
||||
return -1
|
||||
}
|
||||
hostname := req.Options.Get(dhcpv4.OptionHostName)
|
||||
reqIP := req.Options.Get(dhcpv4.OptionRequestedIPAddress)
|
||||
|
||||
// lock
|
||||
switch req.MessageType() {
|
||||
|
||||
lease := s.findLease(mac)
|
||||
if lease == nil {
|
||||
log.Debug("DHCPv6: no lease for: %s", mac)
|
||||
case dhcpv4.MessageTypeDiscover:
|
||||
|
||||
switch req.MessageType() {
|
||||
s.leasesLock.Lock()
|
||||
defer s.leasesLock.Unlock()
|
||||
|
||||
case dhcpv4.MessageTypeDiscover:
|
||||
lease = s.reserveLease(mac)
|
||||
if lease == nil {
|
||||
return false
|
||||
lease = s.findLease(mac)
|
||||
if lease == nil {
|
||||
toStore := false
|
||||
for lease == nil {
|
||||
lease = s.reserveLease(mac)
|
||||
if lease == nil {
|
||||
log.Debug("DHCPv4: No more IP addresses")
|
||||
if toStore {
|
||||
s.conf.notify(LeaseChangedDBStore)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
toStore = true
|
||||
|
||||
if !s.addrAvailable(lease.IP) {
|
||||
s.blacklistLease(lease)
|
||||
lease = nil
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
return false
|
||||
s.conf.notify(LeaseChangedDBStore)
|
||||
|
||||
// s.conf.notify(LeaseChangedBlacklisted)
|
||||
|
||||
} else {
|
||||
if len(reqIP) != 0 &&
|
||||
!bytes.Equal(reqIP, lease.IP) {
|
||||
log.Debug("DHCPv4: different RequestedIP: %v != %v", reqIP, lease.IP)
|
||||
}
|
||||
}
|
||||
|
||||
lease.Hostname = string(hostname)
|
||||
|
||||
resp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeOffer))
|
||||
|
||||
case dhcpv4.MessageTypeRequest:
|
||||
|
||||
sid := req.Options.Get(dhcpv4.OptionServerIdentifier)
|
||||
if len(sid) == 0 {
|
||||
log.Debug("DHCPv4: No OptionServerIdentifier in Request message for %s", mac)
|
||||
return -1
|
||||
}
|
||||
if !bytes.Equal(sid, s.conf.dnsIPAddrs[0]) {
|
||||
log.Debug("DHCPv4: Bad OptionServerIdentifier in Request message for %s", mac)
|
||||
return -1
|
||||
}
|
||||
|
||||
if len(reqIP) != 4 {
|
||||
log.Debug("DHCPv4: Bad OptionRequestedIPAddress in Request message for %s", mac)
|
||||
return -1
|
||||
}
|
||||
|
||||
s.leasesLock.Lock()
|
||||
for _, l := range s.leases {
|
||||
if bytes.Equal(l.HWAddr, mac) {
|
||||
if !bytes.Equal(l.IP, reqIP) {
|
||||
s.leasesLock.Unlock()
|
||||
log.Debug("DHCPv4: Mismatched OptionRequestedIPAddress in Request message for %s", mac)
|
||||
return -1
|
||||
}
|
||||
|
||||
if !bytes.Equal([]byte(l.Hostname), hostname) {
|
||||
s.leasesLock.Unlock()
|
||||
log.Debug("DHCPv4: Mismatched OptionHostName in Request message for %s", mac)
|
||||
return -1
|
||||
}
|
||||
|
||||
lease = l
|
||||
break
|
||||
}
|
||||
}
|
||||
s.leasesLock.Unlock()
|
||||
|
||||
if lease == nil {
|
||||
log.Debug("DHCPv4: No lease for %s", mac)
|
||||
return 0
|
||||
}
|
||||
|
||||
if lease.Expiry.Unix() != leaseExpireStatic {
|
||||
|
||||
lease.Expiry = time.Now().Add(s.conf.leaseTime)
|
||||
|
||||
s.leasesLock.Lock()
|
||||
s.conf.notify(LeaseChangedDBStore)
|
||||
s.leasesLock.Unlock()
|
||||
|
||||
s.conf.notify(LeaseChangedAdded)
|
||||
}
|
||||
|
||||
resp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeAck))
|
||||
}
|
||||
|
||||
err := s.checkIA(req, lease)
|
||||
if err != nil {
|
||||
log.Debug("DHCPv4: %s", err)
|
||||
resp.YourIPAddr = make([]byte, 4)
|
||||
copy(resp.YourIPAddr, lease.IP)
|
||||
|
||||
// return NAK
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
lifetime := s.commitLease(req, lease)
|
||||
resp.UpdateOption(dhcpv4.OptIPAddressLeaseTime(lifetime))
|
||||
|
||||
// resp.UpdateOption(dhcpv4.OptRequestedIPAddress(x))
|
||||
resp.UpdateOption(dhcpv4.OptServerIdentifier(x))
|
||||
resp.UpdateOption(dhcpv4.OptDNS(s.conf.dnsIPAddrs...))
|
||||
resp.UpdateOption(dhcpv4.OptIPAddressLeaseTime(s.conf.leaseTime))
|
||||
resp.UpdateOption(dhcpv4.OptRouter(s.conf.routerIP))
|
||||
resp.UpdateOption(dhcpv4.OptSubnetMask(s.conf.subnetMask))
|
||||
return true
|
||||
resp.UpdateOption(dhcpv4.OptDNS(s.conf.dnsIPAddrs...))
|
||||
return 1
|
||||
}
|
||||
|
||||
// client -> Discover -> server
|
||||
// client <- Reply <- server
|
||||
// client -> Request -> server
|
||||
// client <- Reply <- server
|
||||
// client(0.0.0.0:68) -> (Request:ClientMAC,Discover,ClientID,ReqIP,HostName) -> server(255.255.255.255: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(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) {
|
||||
log.Debug("DHCPv4: received message: %s", req.Summary())
|
||||
|
||||
|
@ -377,8 +472,14 @@ func (s *V4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
|
|||
log.Debug("DHCPv4: dhcpv4.New: %s", err)
|
||||
return
|
||||
}
|
||||
resp.UpdateOption(dhcpv4.OptServerIdentifier(s.conf.dnsIPAddrs[0]))
|
||||
|
||||
_ = s.process(req, resp)
|
||||
r := s.process(req, resp)
|
||||
if r < 0 {
|
||||
return
|
||||
} else if r == 0 {
|
||||
resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak))
|
||||
}
|
||||
|
||||
log.Debug("DHCPv4: sending: %s", resp.Summary())
|
||||
|
||||
|
@ -403,7 +504,7 @@ func getIfaceIPv4(iface net.Interface) []net.IP {
|
|||
continue
|
||||
}
|
||||
if ipnet.IP.To4() != nil {
|
||||
res = append(res, ipnet.IP)
|
||||
res = append(res, ipnet.IP.To4())
|
||||
}
|
||||
}
|
||||
return res
|
||||
|
@ -411,9 +512,13 @@ func getIfaceIPv4(iface net.Interface) []net.IP {
|
|||
|
||||
// Start - start server
|
||||
func (s *V4Server) Start() error {
|
||||
if !s.conf.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
iface, err := net.InterfaceByName(s.conf.InterfaceName)
|
||||
if err != nil {
|
||||
return wrapErrPrint(err, "DHCPv4: Couldn't find interface by name %s", s.conf.InterfaceName)
|
||||
return fmt.Errorf("DHCPv4: Couldn't find interface by name %s: %s", s.conf.InterfaceName, err)
|
||||
}
|
||||
|
||||
log.Debug("DHCPv4: starting...")
|
||||
|
@ -426,7 +531,6 @@ func (s *V4Server) Start() error {
|
|||
IP: net.ParseIP("0.0.0.0"),
|
||||
Port: dhcpv4.ServerPort,
|
||||
}
|
||||
|
||||
server, err := server4.NewServer(iface.Name, laddr, s.packetHandler, server4.WithDebugLogger())
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -446,7 +550,6 @@ func (s *V4Server) Start() error {
|
|||
func (s *V4Server) Reset() {
|
||||
s.leasesLock.Lock()
|
||||
s.leases = nil
|
||||
s.IPpool = make(map[[4]byte]net.HardwareAddr)
|
||||
s.leasesLock.Unlock()
|
||||
}
|
||||
|
||||
|
@ -472,13 +575,34 @@ func v4Create(conf V4ServerConf) (*V4Server, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
s.conf.routerIP = x
|
||||
s.conf.subnetMask = x
|
||||
var err error
|
||||
s.conf.routerIP, err = parseIPv4(s.conf.GatewayIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DHCPv4: %s", err)
|
||||
}
|
||||
|
||||
// s.conf.ipStart = net.ParseIP(conf.RangeStart)
|
||||
// if s.conf.ipStart == nil {
|
||||
// return nil, fmt.Errorf("DHCPv6: invalid range-start IP: %s", conf.RangeStart)
|
||||
// }
|
||||
subnet, err := parseIPv4(s.conf.SubnetMask)
|
||||
if err != nil || !isValidSubnetMask(subnet) {
|
||||
return nil, fmt.Errorf("DHCPv4: invalid subnet mask: %s", s.conf.SubnetMask)
|
||||
}
|
||||
s.conf.subnetMask = make([]byte, 4)
|
||||
copy(s.conf.subnetMask, subnet)
|
||||
|
||||
s.conf.ipStart, err = parseIPv4(conf.RangeStart)
|
||||
if s.conf.ipStart == nil {
|
||||
return nil, fmt.Errorf("DHCPv4: %s", err)
|
||||
}
|
||||
if s.conf.ipStart[0] == 0 {
|
||||
return nil, fmt.Errorf("DHCPv4: invalid range start IP")
|
||||
}
|
||||
s.conf.ipEnd, err = parseIPv4(conf.RangeEnd)
|
||||
if s.conf.ipEnd == nil {
|
||||
return nil, fmt.Errorf("DHCPv4: %s", err)
|
||||
}
|
||||
if !bytes.Equal(s.conf.ipStart[:3], s.conf.ipEnd[:3]) ||
|
||||
s.conf.ipStart[3] > s.conf.ipEnd[3] {
|
||||
return nil, fmt.Errorf("DHCPv4: range end IP should match range start IP")
|
||||
}
|
||||
|
||||
// s.conf.ICMPTimeout = 1000
|
||||
|
||||
|
|
|
@ -467,6 +467,10 @@ func getIfaceIPv6(iface net.Interface) []net.IP {
|
|||
|
||||
// Start - start server
|
||||
func (s *V6Server) Start() error {
|
||||
if !s.conf.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
iface, err := net.InterfaceByName(s.conf.InterfaceName)
|
||||
if err != nil {
|
||||
return wrapErrPrint(err, "Couldn't find interface by name %s", s.conf.InterfaceName)
|
||||
|
|
|
@ -126,10 +126,6 @@ var config = configuration{
|
|||
PortHTTPS: 443,
|
||||
PortDNSOverTLS: 853, // needs to be passed through to dnsproxy
|
||||
},
|
||||
DHCP: dhcpd.ServerConfig{
|
||||
LeaseDuration: 86400,
|
||||
ICMPTimeout: 1000,
|
||||
},
|
||||
SchemaVersion: currentSchemaVersion,
|
||||
}
|
||||
|
||||
|
|
36
home/dhcp.go
36
home/dhcp.go
|
@ -1,36 +0,0 @@
|
|||
package home
|
||||
|
||||
import (
|
||||
"github.com/joomcode/errorx"
|
||||
)
|
||||
|
||||
func startDHCPServer() error {
|
||||
if !config.DHCP.Enabled {
|
||||
// not enabled, don't do anything
|
||||
return nil
|
||||
}
|
||||
|
||||
err := Context.dhcpServer.Init(config.DHCP)
|
||||
if err != nil {
|
||||
return errorx.Decorate(err, "Couldn't init DHCP server")
|
||||
}
|
||||
|
||||
err = Context.dhcpServer.Start()
|
||||
if err != nil {
|
||||
return errorx.Decorate(err, "Couldn't start DHCP server")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stopDHCPServer() error {
|
||||
if !config.DHCP.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := Context.dhcpServer.Stop()
|
||||
if err != nil {
|
||||
return errorx.Decorate(err, "Couldn't stop DHCP server")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -296,7 +296,7 @@ func run(args options) {
|
|||
}
|
||||
}()
|
||||
|
||||
err = startDHCPServer()
|
||||
err = Context.dhcpServer.Start()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ func cleanup() {
|
|||
if err != nil {
|
||||
log.Error("Couldn't stop DNS server: %s", err)
|
||||
}
|
||||
err = stopDHCPServer()
|
||||
err = Context.dhcpServer.Stop()
|
||||
if err != nil {
|
||||
log.Error("Couldn't stop DHCP server: %s", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue