14.04.2026 Update
This commit is contained in:
87
network/overlap.go
Normal file
87
network/overlap.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
type SubnetOverlap struct {
|
||||
Interface string `json:"interface"`
|
||||
Subnet string `json:"subnet"`
|
||||
Label string `json:"label,omitempty"`
|
||||
}
|
||||
|
||||
func parseIPNet(ipStr, maskStr string) (*net.IPNet, error) {
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid IP: %s", ipStr)
|
||||
}
|
||||
ip = ip.To4()
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid IPv4: %s", ipStr)
|
||||
}
|
||||
|
||||
mask := ipMaskFromString(maskStr)
|
||||
if mask == nil {
|
||||
return nil, fmt.Errorf("invalid netmask: %s", maskStr)
|
||||
}
|
||||
|
||||
return &net.IPNet{IP: ip.Mask(mask), Mask: mask}, nil
|
||||
}
|
||||
|
||||
func ipMaskFromString(maskStr string) net.IPMask {
|
||||
m := net.ParseIP(maskStr)
|
||||
if m != nil {
|
||||
if m4 := m.To4(); m4 != nil {
|
||||
return net.IPMask(m4)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func subnetsOverlap(a, b *net.IPNet) bool {
|
||||
return a.Contains(b.IP) || b.Contains(a.IP)
|
||||
}
|
||||
|
||||
func CheckOverlap(newIP, newMask, excludeIface string, existing []SubnetOverlap) []SubnetOverlap {
|
||||
newNet, err := parseIPNet(newIP, newMask)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result []SubnetOverlap
|
||||
for _, s := range existing {
|
||||
if s.Interface == excludeIface {
|
||||
continue
|
||||
}
|
||||
parts, err := parseSubnetStr(s.Subnet)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
existingNet, err := parseIPNet(parts[0], parts[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if subnetsOverlap(newNet, existingNet) {
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ParseSubnet(ipStr, maskStr string) (string, error) {
|
||||
n, err := parseIPNet(ipStr, maskStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return n.String(), nil
|
||||
}
|
||||
|
||||
func parseSubnetStr(s string) ([2]string, error) {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if s[i] == '/' {
|
||||
return [2]string{s[:i], s[i+1:]}, nil
|
||||
}
|
||||
}
|
||||
return [2]string{}, fmt.Errorf("invalid subnet format: %s", s)
|
||||
}
|
||||
Reference in New Issue
Block a user