Introduction
Getting the IP and MAC for your PC is pretty simple, but what if you need those on your local network? It's not as simple as it sounds... in fact it's a complete pain,
and most of the internet articles that Google finds return the MAC for the current PC only. This returns the network list.
Using the code
Console.WriteLine("My IP : {0}", GetIPAddress());
Console.WriteLine("My MAC: {0}", GetMacAddress());
Dictionary<IPAddress, PhysicalAddress> all = GetAllDevicesOnLAN();
foreach (KeyValuePair<IPAddress, PhysicalAddress> kvp in all)
{
Console.WriteLine("IP : {0}\n MAC {1}", kvp.Key, kvp.Value);
}
The code that does the work
[StructLayout(LayoutKind.Sequential)]
struct MIB_IPNETROW
{
[MarshalAs(UnmanagedType.U4)]
public int dwIndex;
[MarshalAs(UnmanagedType.U4)]
public int dwPhysAddrLen;
[MarshalAs(UnmanagedType.U1)]
public byte mac0;
[MarshalAs(UnmanagedType.U1)]
public byte mac1;
[MarshalAs(UnmanagedType.U1)]
public byte mac2;
[MarshalAs(UnmanagedType.U1)]
public byte mac3;
[MarshalAs(UnmanagedType.U1)]
public byte mac4;
[MarshalAs(UnmanagedType.U1)]
public byte mac5;
[MarshalAs(UnmanagedType.U1)]
public byte mac6;
[MarshalAs(UnmanagedType.U1)]
public byte mac7;
[MarshalAs(UnmanagedType.U4)]
public int dwAddr;
[MarshalAs(UnmanagedType.U4)]
public int dwType;
}
[DllImport("IpHlpApi.dll")]
[return: MarshalAs(UnmanagedType.U4)]
static extern int GetIpNetTable(IntPtr pIpNetTable,
[MarshalAs(UnmanagedType.U4)] ref int pdwSize, bool bOrder);
const int ERROR_INSUFFICIENT_BUFFER = 122;
private static Dictionary<IPAddress, PhysicalAddress> GetAllDevicesOnLAN()
{
Dictionary<IPAddress, PhysicalAddress> all = new Dictionary<IPAddress, PhysicalAddress>();
all.Add(GetIPAddress(), GetMacAddress());
int spaceForNetTable = 0;
GetIpNetTable(IntPtr.Zero, ref spaceForNetTable, false);
IntPtr rawTable = IntPtr.Zero;
try
{
rawTable = Marshal.AllocCoTaskMem(spaceForNetTable);
int errorCode = GetIpNetTable(rawTable, ref spaceForNetTable, false);
if (errorCode != 0)
{
throw new Exception(string.Format(
"Unable to retrieve network table. Error code {0}", errorCode));
}
int rowsCount = Marshal.ReadInt32(rawTable);
IntPtr currentBuffer = new IntPtr(rawTable.ToInt64() + Marshal.SizeOf(typeof(Int32)));
MIB_IPNETROW[] rows = new MIB_IPNETROW[rowsCount];
for (int index = 0; index < rowsCount; index++)
{
rows[index] = (MIB_IPNETROW)Marshal.PtrToStructure(new IntPtr(currentBuffer.ToInt64() +
(index * Marshal.SizeOf(typeof(MIB_IPNETROW)))
),
typeof(MIB_IPNETROW));
}
PhysicalAddress virtualMAC = new PhysicalAddress(new byte[] { 0, 0, 0, 0, 0, 0 });
PhysicalAddress broadcastMAC = new PhysicalAddress(new byte[] { 255, 255, 255, 255, 255, 255 });
foreach (MIB_IPNETROW row in rows)
{
IPAddress ip = new IPAddress(BitConverter.GetBytes(row.dwAddr));
byte[] rawMAC = new byte[] { row.mac0, row.mac1, row.mac2, row.mac3, row.mac4, row.mac5 };
PhysicalAddress pa = new PhysicalAddress(rawMAC);
if (!pa.Equals(virtualMAC) && !pa.Equals(broadcastMAC) && !IsMulticast(ip))
{
if (!all.ContainsKey(ip))
{
all.Add(ip, pa);
}
}
}
}
finally
{
Marshal.FreeCoTaskMem(rawTable);
}
return all;
}
private static IPAddress GetIPAddress()
{
String strHostName = Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
foreach (IPAddress ip in addr)
{
if (!ip.IsIPv6LinkLocal)
{
return (ip);
}
}
return addr.Length > 0 ? addr[0] : null;
}
private static PhysicalAddress GetMacAddress()
{
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
nic.OperationalStatus == OperationalStatus.Up)
{
return nic.GetPhysicalAddress();
}
}
return null;
}
private static bool IsMulticast(IPAddress ip)
{
bool result = true;
if (!ip.IsIPv6Multicast)
{
byte highIP = ip.GetAddressBytes()[0];
if (highIP < 224 || highIP > 239)
{
result = false;
}
}
return result;
}
History
Original version.