mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-10-12 01:58:46 +02:00
fix(cli): carry the review fixes of the master port to v1.0
This commit is contained in:
1 parent
12ab2a0e71
commit
f52dfd0354
24 files changed
+993
-68
No files matched your search
@@ -50,34 +50,71 @@ func readNetworkSourceState() (*netmon.State, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return networkSourceState(interfaces, (*net.Interface).Addrs)
|
||||
}
|
||||
|
||||
// networkSourceState builds the state of the given interfaces. The address
|
||||
// reader is a parameter, so a test feeds addresses without a host network.
|
||||
func networkSourceState(interfaces []net.Interface, addressesOf func(*net.Interface) ([]net.Addr, error)) (*netmon.State, error) {
|
||||
state := &netmon.State{Interface: map[string]netmon.Interface{}, InterfaceIPs: map[string][]netip.Prefix{}}
|
||||
for _, iface := range interfaces {
|
||||
addresses, err := iface.Addrs()
|
||||
addresses, err := addressesOf(&iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state.Interface[iface.Name] = netmon.Interface{Interface: &iface}
|
||||
for _, address := range addresses {
|
||||
var ip net.IP
|
||||
switch address := address.(type) {
|
||||
case *net.IPNet:
|
||||
ip = address.IP
|
||||
case *net.IPAddr:
|
||||
ip = address.IP
|
||||
default:
|
||||
return nil, errors.New("unsupported interface address type")
|
||||
prefix, err := interfaceAddressPrefix(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr, ok := netip.AddrFromSlice(ip)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid interface address")
|
||||
}
|
||||
addr = addr.Unmap()
|
||||
state.InterfaceIPs[iface.Name] = append(state.InterfaceIPs[iface.Name], netip.PrefixFrom(addr, addr.BitLen()))
|
||||
state.InterfaceIPs[iface.Name] = append(state.InterfaceIPs[iface.Name], prefix)
|
||||
}
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// interfaceAddressPrefix turns one interface address into a prefix. An address
|
||||
// with a subnet mask keeps the mask and its host bits, so a fresh state shows
|
||||
// the same /24 or /64 as the network monitor. An address without a mask is a
|
||||
// host prefix.
|
||||
func interfaceAddressPrefix(address net.Addr) (netip.Prefix, error) {
|
||||
var ip net.IP
|
||||
var mask net.IPMask
|
||||
switch address := address.(type) {
|
||||
case *net.IPNet:
|
||||
ip, mask = address.IP, address.Mask
|
||||
case *net.IPAddr:
|
||||
ip = address.IP
|
||||
default:
|
||||
return netip.Prefix{}, errors.New("unsupported interface address type")
|
||||
}
|
||||
addr, ok := netip.AddrFromSlice(ip)
|
||||
if !ok {
|
||||
return netip.Prefix{}, errors.New("invalid interface address")
|
||||
}
|
||||
addr = addr.Unmap()
|
||||
return netip.PrefixFrom(addr, prefixBits(addr, mask)), nil
|
||||
}
|
||||
|
||||
// prefixBits reads the length of a mask for an unmapped address. The mask of
|
||||
// an IPv4 address is 4 or 16 bytes long, and a 16-byte mask counts the 96
|
||||
// bits of the IPv6 mapping too. A missing or irregular mask means a host
|
||||
// prefix.
|
||||
func prefixBits(addr netip.Addr, mask net.IPMask) int {
|
||||
bits, total := mask.Size()
|
||||
if total == 0 {
|
||||
return addr.BitLen()
|
||||
}
|
||||
if addr.Is4() && total == 128 {
|
||||
bits -= 96
|
||||
}
|
||||
if bits < 0 || bits > addr.BitLen() {
|
||||
return addr.BitLen()
|
||||
}
|
||||
return bits
|
||||
}
|
||||
|
||||
// netmon v1.74.0 caches only major snapshots. Minor and time-jump events
|
||||
// belong to their Old snapshot, not their distinct New snapshot.
|
||||
func networkSnapshotCurrent(delta *netmon.ChangeDelta, major bool, current *netmon.State) bool {
|
||||
|
||||
Reference in new issue
Block a user