56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
// Package netinfo inspects local IPv4 networks without mutating Windows state.
|
|
package netinfo
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
)
|
|
|
|
// DirectIPv4Prefixes returns assigned non-loopback IPv4 interface prefixes,
|
|
// excluding the named RemLink adapter.
|
|
func DirectIPv4Prefixes(excludedInterface string) ([]netip.Prefix, error) {
|
|
interfaces, err := net.Interfaces()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list network interfaces: %w", err)
|
|
}
|
|
var prefixes []netip.Prefix
|
|
for _, networkInterface := range interfaces {
|
|
if networkInterface.Name == excludedInterface || networkInterface.Flags&net.FlagLoopback != 0 || networkInterface.Flags&net.FlagUp == 0 {
|
|
continue
|
|
}
|
|
addresses, err := networkInterface.Addrs()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list addresses for %s: %w", networkInterface.Name, err)
|
|
}
|
|
for _, address := range addresses {
|
|
prefix, err := netip.ParsePrefix(address.String())
|
|
if err != nil || !prefix.Addr().Is4() {
|
|
continue
|
|
}
|
|
prefixes = append(prefixes, prefix.Masked())
|
|
}
|
|
}
|
|
return prefixes, nil
|
|
}
|
|
|
|
// PrefixesOverlap performs true containment-based IPv4 prefix overlap.
|
|
func PrefixesOverlap(left, right netip.Prefix) bool {
|
|
if !left.Addr().Is4() || !right.Addr().Is4() {
|
|
return false
|
|
}
|
|
left = left.Masked()
|
|
right = right.Masked()
|
|
return left.Contains(right.Addr()) || right.Contains(left.Addr())
|
|
}
|
|
|
|
// FindConflict returns the first local network overlapping desired.
|
|
func FindConflict(desired netip.Prefix, existing []netip.Prefix) (netip.Prefix, bool) {
|
|
for _, candidate := range existing {
|
|
if PrefixesOverlap(desired, candidate) {
|
|
return candidate, true
|
|
}
|
|
}
|
|
return netip.Prefix{}, false
|
|
}
|