in src/PSRule.Rules.Azure/Data/Template/CidrParsing.cs [139:202]
private static bool TryGetInfo(byte[] address, int prefixLength, int subnetOffset, int hostOffset, out ICidrInfo info)
{
var numBytes = address.Length;
var offset = (byte)(numBytes == 4 && prefixLength < 32 ? 1 : 0);
// Fill in the mask
var netmask = new byte[numBytes];
for (var i = 0; i < prefixLength; i++)
{
netmask[i / 8] |= (byte)(1 << (7 - (i % 8)));
}
// Mask the address to get the address
var network = new byte[numBytes];
for (var i = 0; i < numBytes; i++)
{
network[i] = (byte)(address[i] & netmask[i]);
}
// Calculate the network based on the netmask and offset by subnetOffset
var networkAddress = new byte[numBytes];
var carry = subnetOffset << (8 - (prefixLength % 8));
for (var i = numBytes - (numBytes - prefixLength / 8); i >= 0; i--)
{
if (i == numBytes)
i--;
networkAddress[i] = (byte)((address[i] & network[i]) + carry);
carry = (byte)(((address[i] & network[i]) + carry) >> 8);
}
// Calculate the first address based on netmask
var firstAddress = new byte[numBytes];
for (var i = 0; i < numBytes; i++)
{
firstAddress[i] = (byte)(network[i] + ((i == numBytes - 1) ? (offset + hostOffset) : 0));
}
// Calculate the broadcast
var broadcastAddress = new byte[numBytes];
for (var i = 0; i < numBytes; i++)
{
broadcastAddress[i] = (byte)(networkAddress[i] + ((i >= prefixLength / 8) ? 255 - netmask[i] : 0));
}
// Calculate the last usable address based on broadcast
var lastUsableAddress = new byte[numBytes];
for (var i = 0; i < numBytes; i++)
{
lastUsableAddress[i] = (byte)(broadcastAddress[i] - ((i == numBytes - 1) ? offset : 0));
}
info = new CidrInfo
{
Version = numBytes == 4 ? 4 : 6,
Network = new CidrIP(networkAddress),
Netmask = new CidrIP(netmask),
Broadcast = new CidrIP(broadcastAddress),
FirstUsable = new CidrIP(firstAddress),
LastUsable = new CidrIP(lastUsableAddress),
Cidr = prefixLength,
};
return true;
}