2023-05-03 02:57:04 +00:00
|
|
|
package iptools
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/netip"
|
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type LeaseInfo struct {
|
|
|
|
HostName string `yaml:"hostname"`
|
|
|
|
Addr netip.Addr `yaml:"addr"`
|
|
|
|
HardwareAddress HardwareAddress `yaml:"mac_addr"`
|
|
|
|
Expires time.Time `yaml:"expires"`
|
|
|
|
}
|
|
|
|
|
2023-05-09 07:28:54 +00:00
|
|
|
func (li *LeaseInfo) String() string {
|
|
|
|
return fmt.Sprintf("lease[hostname=%s addr=%s hw=%x expires=%s]", li.HostName, li.Addr, li.HardwareAddress, li.Expires)
|
|
|
|
}
|
|
|
|
|
2023-05-06 05:21:27 +00:00
|
|
|
type sortableLease []*LeaseInfo
|
2023-05-03 02:57:04 +00:00
|
|
|
|
|
|
|
func (a sortableLease) Len() int { return len(a) }
|
|
|
|
func (a sortableLease) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
|
|
func (a sortableLease) Less(i, j int) bool { return a[i].Addr.Less(a[j].Addr) }
|
|
|
|
|
|
|
|
func (li *LeaseInfo) ResetExpiry(t time.Time, dur time.Duration) {
|
|
|
|
li.Expires = t.Add(dur)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (li *LeaseInfo) IsExpired(t time.Time) bool {
|
|
|
|
return t.After(li.Expires)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (li *LeaseInfo) Expire() {
|
|
|
|
li.Expires = time.Time{}
|
|
|
|
}
|
|
|
|
|
2023-05-06 05:21:27 +00:00
|
|
|
func SortLeases(leases []*LeaseInfo) []*LeaseInfo {
|
2023-05-03 02:57:04 +00:00
|
|
|
sortable := sortableLease(leases)
|
|
|
|
sort.Sort(sortable)
|
|
|
|
|
2023-05-06 05:21:27 +00:00
|
|
|
return []*LeaseInfo(sortable)
|
2023-05-03 02:57:04 +00:00
|
|
|
}
|
|
|
|
|
2023-05-06 05:21:27 +00:00
|
|
|
func (lease *LeaseInfo) Reset() *LeaseInfo {
|
2023-05-03 02:57:04 +00:00
|
|
|
lease.Expires = time.Time{}
|
|
|
|
lease.HardwareAddress = nil
|
|
|
|
return lease
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lease LeaseInfo) Compare(other LeaseInfo) error {
|
|
|
|
susFields := []string{}
|
|
|
|
|
|
|
|
if lease.Addr != other.Addr {
|
|
|
|
susFields = append(susFields, fmt.Sprintf("address is %s, but is recorded as %s", lease.Addr, other.Addr))
|
|
|
|
}
|
|
|
|
|
|
|
|
if !lease.HardwareAddress.Match(other.HardwareAddress) {
|
|
|
|
susFields = append(susFields, fmt.Sprintf("hardware address is %s, but is recorded as %s", lease.HardwareAddress, other.HardwareAddress))
|
|
|
|
}
|
|
|
|
|
|
|
|
if lease.HostName != other.HostName {
|
|
|
|
susFields = append(susFields, fmt.Sprintf("hostname is %s, but is recorded as %s", lease.HostName, other.HostName))
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(susFields) > 0 {
|
|
|
|
return fmt.Errorf("suspicious lease: %s", strings.Join(susFields, ";"))
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|