39 lines
878 B
Go
39 lines
878 B
Go
|
package cidr
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math/big"
|
||
|
"net"
|
||
|
)
|
||
|
|
||
|
func ipToInt(ip net.IP) (*big.Int, int) {
|
||
|
val := &big.Int{}
|
||
|
val.SetBytes([]byte(ip))
|
||
|
if len(ip) == net.IPv4len {
|
||
|
return val, 32
|
||
|
} else if len(ip) == net.IPv6len {
|
||
|
return val, 128
|
||
|
} else {
|
||
|
panic(fmt.Errorf("Unsupported address length %d", len(ip)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func intToIP(ipInt *big.Int, bits int) net.IP {
|
||
|
ipBytes := ipInt.Bytes()
|
||
|
ret := make([]byte, bits/8)
|
||
|
// Pack our IP bytes into the end of the return array,
|
||
|
// since big.Int.Bytes() removes front zero padding.
|
||
|
for i := 1; i <= len(ipBytes); i++ {
|
||
|
ret[len(ret)-i] = ipBytes[len(ipBytes)-i]
|
||
|
}
|
||
|
return net.IP(ret)
|
||
|
}
|
||
|
|
||
|
func insertNumIntoIP(ip net.IP, num int, prefixLen int) net.IP {
|
||
|
ipInt, totalBits := ipToInt(ip)
|
||
|
bigNum := big.NewInt(int64(num))
|
||
|
bigNum.Lsh(bigNum, uint(totalBits-prefixLen))
|
||
|
ipInt.Or(ipInt, bigNum)
|
||
|
return intToIP(ipInt, totalBits)
|
||
|
}
|