diff --git a/internal/dhcpd/http_unix.go b/internal/dhcpd/http_unix.go index bbfdd973..22f80443 100644 --- a/internal/dhcpd/http_unix.go +++ b/internal/dhcpd/http_unix.go @@ -502,6 +502,8 @@ func (s *server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request return } + l.IP = l.IP.Unmap() + var srv DHCPServer if l.IP.Is4() { srv = s.srv4 diff --git a/internal/dhcpd/v4_unix.go b/internal/dhcpd/v4_unix.go index 5a891d94..a7d1565b 100644 --- a/internal/dhcpd/v4_unix.go +++ b/internal/dhcpd/v4_unix.go @@ -212,7 +212,7 @@ func (s *v4Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { } for _, l := range s.leases { - if l.IP.Compare(ip) == 0 { + if l.IP == ip { if l.Expiry.After(now) || l.IsStatic() { return l.HWAddr } @@ -246,8 +246,8 @@ func (s *v4Server) rmLeaseByIndex(i int) { s.leases = append(s.leases[:i], s.leases[i+1:]...) r := s.conf.ipRange - ip := net.IP(l.IP.AsSlice()) - offset, ok := r.offset(ip) + leaseIP := net.IP(l.IP.AsSlice()) + offset, ok := r.offset(leaseIP) if ok { s.leasedOffsets.set(offset, false) } @@ -263,7 +263,7 @@ func (s *v4Server) rmDynamicLease(lease *Lease) (err error) { for i, l := range s.leases { isStatic := l.IsStatic() - if bytes.Equal(l.HWAddr, lease.HWAddr) || (l.IP.Compare(lease.IP) == 0) { + if bytes.Equal(l.HWAddr, lease.HWAddr) || l.IP == lease.IP { if isStatic { return errors.Error("static lease already exists") } @@ -291,14 +291,13 @@ const ErrDupHostname = errors.Error("hostname is not unique") // addLease adds a dynamic or static lease. func (s *v4Server) addLease(l *Lease) (err error) { r := s.conf.ipRange - ip := net.IP(l.IP.AsSlice()) - offset, inOffset := r.offset(ip) + leaseIP := net.IP(l.IP.AsSlice()) + offset, inOffset := r.offset(leaseIP) if l.IsStatic() { // TODO(a.garipov, d.seregin): Subnet can be nil when dhcp server is // disabled. - addr := netip.AddrFrom4(*(*[4]byte)(ip.To4())) - if sn := s.conf.subnet; !sn.Contains(addr) { + if sn := s.conf.subnet; !sn.Contains(l.IP) { return fmt.Errorf("subnet %s does not contain the ip %q", sn, l.IP) } } else if !inOffset { @@ -326,7 +325,7 @@ func (s *v4Server) rmLease(lease *Lease) (err error) { } for i, l := range s.leases { - if l.IP.Compare(lease.IP) == 0 { + if l.IP == lease.IP { if !bytes.Equal(l.HWAddr, lease.HWAddr) || l.Hostname != lease.Hostname { return fmt.Errorf("lease for ip %s is different: %+v", lease.IP, l) } @@ -353,11 +352,9 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) { return ErrUnconfigured } - ip := net.IP(l.IP.AsSlice()) - ip = ip.To4() - if ip == nil { + if !l.IP.Is4() { return fmt.Errorf("invalid ip %q, only ipv4 is supported", l.IP) - } else if gwIP := s.conf.GatewayIP; gwIP == netip.AddrFrom4(*(*[4]byte)(ip)) { + } else if gwIP := s.conf.GatewayIP; gwIP == l.IP { return fmt.Errorf("can't assign the gateway IP %s to the lease", gwIP) } @@ -398,7 +395,7 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) { if err != nil { err = fmt.Errorf( "removing dynamic leases for %s (%s): %w", - ip, + l.IP, l.HWAddr, err, ) @@ -408,7 +405,7 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) { err = s.addLease(l) if err != nil { - err = fmt.Errorf("adding static lease for %s (%s): %w", ip, l.HWAddr, err) + err = fmt.Errorf("adding static lease for %s (%s): %w", l.IP, l.HWAddr, err) return } @@ -612,8 +609,8 @@ func (s *v4Server) allocateLease(mac net.HardwareAddr) (l *Lease, err error) { return nil, nil } - ip := l.IP.AsSlice() - if s.addrAvailable(ip) { + leaseIP := l.IP.AsSlice() + if s.addrAvailable(leaseIP) { return l, nil } @@ -633,9 +630,9 @@ func (s *v4Server) handleDiscover(req, resp *dhcpv4.DHCPv4) (l *Lease, err error l = s.findLease(mac) if l != nil { reqIP := req.RequestedIPAddress() - ip := net.IP(l.IP.AsSlice()) - if len(reqIP) != 0 && !reqIP.Equal(ip) { - log.Debug("dhcpv4: different RequestedIP: %s != %s", reqIP, ip) + leaseIP := net.IP(l.IP.AsSlice()) + if len(reqIP) != 0 && !reqIP.Equal(leaseIP) { + log.Debug("dhcpv4: different RequestedIP: %s != %s", reqIP, leaseIP) } resp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeOffer)) @@ -685,13 +682,17 @@ func (s *v4Server) checkLease(mac net.HardwareAddr, ip net.IP) (lease *Lease, mi s.leasesLock.Lock() defer s.leasesLock.Unlock() + netIP, ok := netip.AddrFromSlice(ip) + if !ok { + log.Info("check lease: invalid IP: %s", ip) + } + for _, l := range s.leases { if !bytes.Equal(l.HWAddr, mac) { continue } - leaseIP := net.IP(l.IP.AsSlice()) - if leaseIP.Equal(ip) { + if l.IP == netIP { return l, false } @@ -890,10 +891,16 @@ func (s *v4Server) handleDecline(req, resp *dhcpv4.DHCPv4) (err error) { reqIP = req.ClientIPAddr } + netIP, ok := netip.AddrFromSlice(reqIP) + if !ok { + log.Info("dhcpv4: invalid IP: %s", reqIP) + + return nil + } + var oldLease *Lease for _, l := range s.leases { - ip := net.IP(l.IP.AsSlice()) - if bytes.Equal(l.HWAddr, mac) && ip.Equal(reqIP) { + if bytes.Equal(l.HWAddr, mac) && l.IP == netIP { oldLease = l break @@ -933,9 +940,7 @@ func (s *v4Server) handleDecline(req, resp *dhcpv4.DHCPv4) (err error) { log.Info("dhcpv4: changed ip from %s to %s for %s", reqIP, newLease.IP, mac) - resp.YourIPAddr = make([]byte, 4) - ip := net.IP(newLease.IP.AsSlice()) - copy(resp.YourIPAddr, ip) + resp.YourIPAddr = net.IP(newLease.IP.AsSlice()) resp.UpdateOption(dhcpv4.OptMessageType(dhcpv4.MessageTypeAck)) @@ -958,9 +963,15 @@ func (s *v4Server) handleRelease(req, resp *dhcpv4.DHCPv4) (err error) { s.leasesLock.Lock() defer s.leasesLock.Unlock() + netIP, ok := netip.AddrFromSlice(reqIP) + if !ok { + log.Info("dhcpv4: invalid IP: %s", reqIP) + + return nil + } + for _, l := range s.leases { - ip := net.IP(l.IP.AsSlice()) - if !bytes.Equal(l.HWAddr, mac) || !ip.Equal(reqIP) { + if !bytes.Equal(l.HWAddr, mac) || l.IP != netIP { continue } diff --git a/internal/dhcpd/v4_unix_test.go b/internal/dhcpd/v4_unix_test.go index 22a01cec..474f4caf 100644 --- a/internal/dhcpd/v4_unix_test.go +++ b/internal/dhcpd/v4_unix_test.go @@ -326,7 +326,7 @@ func TestV4_AddReplace(t *testing.T) { require.Len(t, ls, 2) for i, l := range ls { - assert.True(t, stLeases[i].IP.Compare(l.IP) == 0) + assert.Equal(t, stLeases[i].IP, l.IP) assert.Equal(t, stLeases[i].HWAddr, l.HWAddr) assert.True(t, l.IsStatic()) } @@ -593,7 +593,7 @@ func TestV4StaticLease_Get(t *testing.T) { ls := s.GetLeases(LeasesStatic) require.Len(t, ls, 1) - assert.True(t, l.IP.Compare(ls[0].IP) == 0) + assert.Equal(t, l.IP, ls[0].IP) assert.Equal(t, mac, ls[0].HWAddr) }) } @@ -692,7 +692,7 @@ func TestV4DynamicLease_Get(t *testing.T) { require.Len(t, ls, 1) ip := netip.MustParseAddr("192.168.10.100") - assert.True(t, ip.Compare(ls[0].IP) == 0) + assert.Equal(t, ip, ls[0].IP) assert.Equal(t, mac, ls[0].HWAddr) }) } diff --git a/internal/dhcpd/v6_unix.go b/internal/dhcpd/v6_unix.go index 95bd33ad..7ecf4499 100644 --- a/internal/dhcpd/v6_unix.go +++ b/internal/dhcpd/v6_unix.go @@ -120,7 +120,7 @@ func (s *v6Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { } for _, l := range s.leases { - if l.IP.Compare(ip) == 0 { + if l.IP == ip { if l.Expiry.After(now) || l.IsStatic() { return l.HWAddr } @@ -132,8 +132,8 @@ func (s *v6Server) FindMACbyIP(ip netip.Addr) (mac net.HardwareAddr) { // Remove (swap) lease by index func (s *v6Server) leaseRemoveSwapByIndex(i int) { - ip := s.leases[i].IP.AsSlice() - s.ipAddrs[ip[15]] = 0 + leaseIP := s.leases[i].IP.AsSlice() + s.ipAddrs[leaseIP[15]] = 0 log.Debug("dhcpv6: removed lease %s", s.leases[i].HWAddr) n := len(s.leases) @@ -162,7 +162,7 @@ func (s *v6Server) rmDynamicLease(lease *Lease) (err error) { l = s.leases[i] } - if l.IP.Compare(lease.IP) == 0 { + if l.IP == lease.IP { if l.Expiry.Unix() == leaseExpireStatic { return fmt.Errorf("static lease already exists") } @@ -242,7 +242,7 @@ func (s *v6Server) addLease(l *Lease) { // Remove a lease with the same properties func (s *v6Server) rmLease(lease *Lease) (err error) { for i, l := range s.leases { - if l.IP.Compare(lease.IP) == 0 { + if l.IP == lease.IP { if !bytes.Equal(l.HWAddr, lease.HWAddr) || l.Hostname != lease.Hostname { return fmt.Errorf("lease not found") @@ -398,8 +398,8 @@ func (s *v6Server) checkIA(msg *dhcpv6.Message, lease *Lease) error { return fmt.Errorf("no IANA.Addr option in %s", msg.Type().String()) } - ip := net.IP(lease.IP.AsSlice()) - if !oiaAddr.IPv6Addr.Equal(ip) { + leaseIP := net.IP(lease.IP.AsSlice()) + if !oiaAddr.IPv6Addr.Equal(leaseIP) { return fmt.Errorf("invalid IANA.Addr option in %s", msg.Type().String()) } } diff --git a/internal/dhcpd/v6_unix_test.go b/internal/dhcpd/v6_unix_test.go index 178fdf35..7a588054 100644 --- a/internal/dhcpd/v6_unix_test.go +++ b/internal/dhcpd/v6_unix_test.go @@ -101,7 +101,7 @@ func TestV6_AddReplace(t *testing.T) { require.Len(t, ls, 2) for i, l := range ls { - assert.True(t, stLeases[i].IP.Compare(l.IP) == 0) + assert.Equal(t, stLeases[i].IP, l.IP) assert.Equal(t, stLeases[i].HWAddr, l.HWAddr) assert.EqualValues(t, leaseExpireStatic, l.Expiry.Unix()) } diff --git a/internal/dnsforward/dns.go b/internal/dnsforward/dns.go index 3de37bc2..e48a30ca 100644 --- a/internal/dnsforward/dns.go +++ b/internal/dnsforward/dns.go @@ -249,10 +249,10 @@ func (s *Server) onDHCPLeaseChanged(flags int) { continue } - ip := l.IP + leaseIP := l.IP - ipToHost[ip] = lowhost - hostToIP[lowhost] = ip + ipToHost[leaseIP] = lowhost + hostToIP[lowhost] = leaseIP } s.setTableHostToIP(hostToIP)