// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Net;
namespace UnrealBuildTool
{
///
/// Represents an IP subnet
///
class Subnet
{
///
/// The prefix address
///
public IPAddress Prefix
{
get;
private set;
}
///
/// Number of bits that need to match in an IP address for this subnet
///
public int MaskBits
{
get;
private set;
}
///
/// Bytes corresponding to the prefix address
///
byte[] PrefixBytes;
///
/// Constructor
///
/// The prefix IP address
/// Number of bits to match for this subnet
public Subnet(IPAddress Prefix, int MaskBits)
{
this.Prefix = Prefix;
PrefixBytes = Prefix.GetAddressBytes();
this.MaskBits = MaskBits;
}
///
/// Parses a subnet from a string
///
/// The string to parse
/// New subnet that was parsed
public static Subnet Parse(string Text)
{
int SlashIdx = Text.IndexOf('/');
IPAddress Address = IPAddress.Parse(Text.Substring(0, SlashIdx));
return new Subnet(Address, Int32.Parse(Text.Substring(SlashIdx + 1)));
}
///
/// Checks if this subnet contains the given address
///
/// IP address to test
/// True if the subnet contains this address
public bool Contains(IPAddress Address)
{
return Contains(Address.GetAddressBytes());
}
///
/// Checks if this subnet contains the given address bytes
///
/// Bytes of the IP address to text
/// True if the subnet contains this address
public bool Contains(byte[] Bytes)
{
if (Bytes.Length != PrefixBytes.Length)
{
return false;
}
int Index = 0;
int RemainingBits = MaskBits;
// Check all the full bytes first
for (; RemainingBits >= 8; RemainingBits -= 8)
{
if (Bytes[Index] != PrefixBytes[Index])
{
return false;
}
Index++;
}
// Check the remaining bits
if (RemainingBits > 0)
{
int LastMaskByte = ((1 << RemainingBits) - 1) << (8 - RemainingBits);
if ((Bytes[Index] & LastMaskByte) != (PrefixBytes[Index] & LastMaskByte))
{
return false;
}
}
return true;
}
///
/// Formats this subnet as text
///
/// String representation of the subnet
public override string ToString()
{
return String.Format("{0}/{1}", Prefix, MaskBits);
}
}
}