using System;
using System.Linq;
namespace Cosmos.HAL.Network
{
public class MACAddress : IComparable
{
public static MACAddress Broadcast;
public static MACAddress None;
static MACAddress()
{
var xBroadcastArray = new byte[6];
xBroadcastArray[0] = 0xFF;
xBroadcastArray[1] = 0xFF;
xBroadcastArray[2] = 0xFF;
xBroadcastArray[3] = 0xFF;
xBroadcastArray[4] = 0xFF;
xBroadcastArray[5] = 0xFF;
Broadcast = new MACAddress(xBroadcastArray);
var xNoneArray = new byte[6];
xNoneArray[0] = 0x00;
xNoneArray[1] = 0x00;
xNoneArray[2] = 0x00;
xNoneArray[3] = 0x00;
xNoneArray[4] = 0x00;
xNoneArray[5] = 0x00;
None = new MACAddress(xNoneArray);
}
public byte[] bytes = new byte[6];
public MACAddress(byte[] address)
{
if (address == null || address.Length != 6)
throw new ArgumentException("MACAddress is null or has wrong length", "address");
bytes[0] = address[0];
bytes[1] = address[1];
bytes[2] = address[2];
bytes[3] = address[3];
bytes[4] = address[4];
bytes[5] = address[5];
}
///
/// Create a MAC address from a byte buffer starting at the specified offset
///
/// byte buffer
/// offset in buffer to start from
public MACAddress(byte[] buffer, int offset)
{
if (buffer == null || buffer.Length < (offset + 6))
throw new ArgumentException("buffer does not contain enough data starting at offset", "buffer");
bytes[0] = buffer[offset];
bytes[1] = buffer[offset + 1];
bytes[2] = buffer[offset + 2];
bytes[3] = buffer[offset + 3];
bytes[4] = buffer[offset + 4];
bytes[5] = buffer[offset + 5];
}
public MACAddress(MACAddress m)
: this(m.bytes)
{
}
public bool IsValid()
{
return bytes != null && bytes.Length == 6;
}
public int CompareTo(object obj)
{
if (obj is MACAddress)
{
MACAddress other = (MACAddress)obj;
int i = 0;
i = bytes[0].CompareTo(other.bytes[0]);
if (i != 0) return i;
i = bytes[1].CompareTo(other.bytes[1]);
if (i != 0) return i;
i = bytes[2].CompareTo(other.bytes[2]);
if (i != 0) return i;
i = bytes[3].CompareTo(other.bytes[3]);
if (i != 0) return i;
i = bytes[4].CompareTo(other.bytes[4]);
if (i != 0) return i;
i = bytes[5].CompareTo(other.bytes[5]);
if (i != 0) return i;
return 0;
}
else
throw new ArgumentException("obj is not a MACAddress", "obj");
}
public override bool Equals(object obj)
{
if (obj is MACAddress)
{
MACAddress other = (MACAddress)obj;
return bytes[0] == other.bytes[0] &&
bytes[1] == other.bytes[1] &&
bytes[2] == other.bytes[2] &&
bytes[3] == other.bytes[3] &&
bytes[4] == other.bytes[4] &&
bytes[5] == other.bytes[5];
}
else
throw new ArgumentException("obj is not a MACAddress", "obj");
}
public override int GetHashCode()
{
return (GetType().AssemblyQualifiedName + "|" + this.ToString()).GetHashCode();
}
public UInt64 ToNumber()
{
return (UInt64)((bytes[0] << 40) | (bytes[1] << 32) | (bytes[2] << 24) | (bytes[3] << 16) |
(bytes[4] << 8) | (bytes[5] << 0));
}
private static void PutByte(char[] aChars, int aIndex, byte aByte)
{
string xChars = "0123456789ABCDEF";
aChars[aIndex + 0] = xChars[(aByte >> 4) & 0xF];
aChars[aIndex + 1] = xChars[aByte & 0xF];
}
public override string ToString()
{
// mac address consists of 6 2chars pairs, delimited by :
var xChars = new char[17];
PutByte(xChars, 0, bytes[0]);
xChars[2] = ':';
PutByte(xChars, 3, bytes[1]);
xChars[5] = ':';
PutByte(xChars, 6, bytes[2]);
xChars[8] = ':';
PutByte(xChars, 9, bytes[3]);
xChars[11] = ':';
PutByte(xChars, 12, bytes[4]);
xChars[14] = ':';
PutByte(xChars, 15, bytes[5]);
return new String(xChars);
}
public UInt32 to32BitNumber()
{
return (UInt32)((bytes[0] << 40) | (bytes[1] << 32) | (bytes[2] << 24) | (bytes[3] << 16) |
(bytes[4] << 8) | (bytes[5] << 0));
}
private UInt32 hash;
///
/// Hash value for this mac. Used to uniquely identify each mac
///
public UInt32 Hash
{
get
{
if (hash == 0)
{
hash = to32BitNumber();
}
return hash;
}
}
}
}