using System; namespace Cosmos.System.Network.IPv4 { /// /// Address class, used to define a IPv4 address. /// Should actually be using System.Net.IPAddress, but gives problems. /// public class Address : IComparable { /// /// Predefined 0.0.0.0 address. /// public static Address Zero = new Address(0, 0, 0, 0); /// /// Broadcast address (255.255.255.255). /// public static Address Broadcast = new Address(255, 255, 255, 255); /// /// address as byte array. /// internal byte[] address = new byte[4]; /// /// Create new inctanse of the class, with specified IP address. /// /// First block of the address. /// Second block of the address. /// Third block of the address. /// Fourth block of the address. public Address(byte aFirst, byte aSecond, byte aThird, byte aFourth) { address[0] = aFirst; address[1] = aSecond; address[2] = aThird; address[3] = aFourth; } /// /// Create new inctanse of the class, with specified buffer and offset. /// /// Buffer. /// Offset. /// Thrown if buffer is invalid or null. public Address(byte[] buffer, int offset) { if (buffer == null || buffer.Length < (offset + 4)) throw new ArgumentException("buffer does not contain enough data starting at offset", "buffer"); address[0] = buffer[offset]; address[1] = buffer[offset + 1]; address[2] = buffer[offset + 2]; address[3] = buffer[offset + 3]; } /// /// Parse a IP address in string representation. /// /// IP address as string. /// Address value. /// Thrown if adr is longer than Int32.MaxValue. /// Thrown if adr is null. /// Thrown if adr is not in the right format. /// Thrown if adr represents a number less than Byte.MinValue or greater than Byte.MaxValue. public static Address Parse(string adr) { string[] fragments = adr.Split('.'); if (fragments.Length == 4) { byte first = byte.Parse(fragments[0]); byte second = byte.Parse(fragments[1]); byte third = byte.Parse(fragments[2]); byte fourth = byte.Parse(fragments[3]); return new Address(first, second, third, fourth); } else { return null; } } /// /// Check if address is a loopback address. /// /// public bool IsLoopbackAddress() { if (address[0] == 127) return true; else return false; } /// /// Check if address is a broadcast address. /// /// public bool IsBroadcastAddress() => address[0] == 0xFF && address[1] == 0xFF && address[2] == 0xFF && address[3] == 0xFF; /// /// Check if address is a APIPA address. /// /// public bool IsAPIPA() { if ((address[0] == 169) && (address[1] == 254)) { return true; } return false; } /// /// Converts IP Address to String. /// /// String with IP Address in dotted notation public override string ToString() { return address[0] + "." + address[1] + "." + address[2] + "." + address[3]; } /// /// Convert address to byte array. /// /// public byte[] ToByteArray() { return address; } /// /// Convert address to 32 bit number. /// /// UInt32 value. private UInt32 to32BitNumber() { return (UInt32)((address[0] << 24) | (address[1] << 16) | (address[2] << 8) | (address[3] << 0)); } /// /// Hashed value for the IP. /// private UInt32 hash; /// /// Hash value for this IP. Used to uniquely identify each IP /// public UInt32 Hash { get { if (hash == 0) { hash = to32BitNumber(); } return hash; } } #region IComparable Members /// /// Compare 2 IP Address objects for equality /// /// Other IP to compare with. /// 0 if equal, or non-zero otherwise /// Thrown if obj is not a IPv4Address. public int CompareTo(object obj) { if (obj is Address) { Address other = (Address)obj; if (other.hash != this.hash) { return -1; } return 0; } else throw new ArgumentException("obj is not a IPv4Address", "obj"); } #endregion } }