mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2024-11-16 11:42:43 +08:00
74 lines
1.5 KiB
Go
74 lines
1.5 KiB
Go
package nnip
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"net"
|
|
"net/netip"
|
|
)
|
|
|
|
// IpToAddr converts the net.IP to netip.Addr.
|
|
// If slice's length is not 4 or 16, IpToAddr returns netip.Addr{}
|
|
func IpToAddr(slice net.IP) netip.Addr {
|
|
ip := slice
|
|
if len(ip) != 4 {
|
|
if ip = slice.To4(); ip == nil {
|
|
ip = slice
|
|
}
|
|
}
|
|
|
|
if addr, ok := netip.AddrFromSlice(ip); ok {
|
|
return addr
|
|
}
|
|
return netip.Addr{}
|
|
}
|
|
|
|
// UnMasked returns p's last IP address.
|
|
// If p is invalid, UnMasked returns netip.Addr{}
|
|
func UnMasked(p netip.Prefix) netip.Addr {
|
|
if !p.IsValid() {
|
|
return netip.Addr{}
|
|
}
|
|
|
|
buf := p.Addr().As16()
|
|
|
|
hi := binary.BigEndian.Uint64(buf[:8])
|
|
lo := binary.BigEndian.Uint64(buf[8:])
|
|
|
|
bits := p.Bits()
|
|
if bits <= 32 {
|
|
bits += 96
|
|
}
|
|
|
|
hi = hi | ^uint64(0)>>bits
|
|
lo = lo | ^(^uint64(0) << (128 - bits))
|
|
|
|
binary.BigEndian.PutUint64(buf[:8], hi)
|
|
binary.BigEndian.PutUint64(buf[8:], lo)
|
|
|
|
addr := netip.AddrFrom16(buf)
|
|
if p.Addr().Is4() {
|
|
return addr.Unmap()
|
|
}
|
|
return addr
|
|
}
|
|
|
|
// PrefixCompare returns an integer comparing two prefixes.
|
|
// The result will be 0 if p == p2, -1 if p < p2, and +1 if p > p2.
|
|
// modify from https://github.com/golang/go/issues/61642#issuecomment-1848587909
|
|
func PrefixCompare(p, p2 netip.Prefix) int {
|
|
// compare by validity, address family and prefix base address
|
|
if c := p.Masked().Addr().Compare(p2.Masked().Addr()); c != 0 {
|
|
return c
|
|
}
|
|
// compare by prefix length
|
|
f1, f2 := p.Bits(), p2.Bits()
|
|
if f1 < f2 {
|
|
return -1
|
|
}
|
|
if f1 > f2 {
|
|
return 1
|
|
}
|
|
// compare by prefix address
|
|
return p.Addr().Compare(p2.Addr())
|
|
}
|