Scanning your entire LAN for MAC Addresses

Not too long ago, I wrote a network administration utility with specific needs.

One of the needs was to scan all the LAN pool for MAC addresses.

The code will look at your active network adapters, calculate start and end IP according to your address and netmask,

and query all the IPs within that range for their MAC address.

The code is written in C#, and it's basically going over the whole range in a nested loop.

If you find this useful, you are welcome to use the code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.NetworkInformation;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;

private static void StartScan()
{
    foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) {
	if (ni.OperationalStatus == OperationalStatus.Down)
	    continue;
	if (ni.GetIPProperties().GatewayAddresses.Count == 0)
	    continue;
	foreach(UnicastIPAddressInformation uipi in ni.GetIPProperties().UnicastAddresses) {
	    if (uipi.IPv4Mask == null)
		continue;
	    System.Console.WriteLine("IP: " + uipi.Address + ", Netmask: " + uipi.IPv4Mask);
	    String[]IPParts = uipi.Address.ToString().Split('.');
	    String[]NetmaskParts = uipi.IPv4Mask.ToString().Split('.');
	    String StartIP;
	    StartIP = (int.Parse(IPParts[0]) & (int.Parse(NetmaskParts[0]))) +"." + (int.Parse(IPParts[1]) & (int.Parse(NetmaskParts[1]))) +"." + (int.Parse(IPParts[2]) & (int.Parse(NetmaskParts[2]))) +"." + (int.Parse(IPParts[3]) & (int.Parse(NetmaskParts[3])));
	    String EndIP;
	    String[]StartIPParts = StartIP.Split('.');
	    EndIP = (int.Parse(StartIPParts[0]) + 255 - (int.Parse(NetmaskParts[0]))) +"." + (int.Parse(StartIPParts[1]) + 255 - (int.Parse(NetmaskParts[1]))) +"." + (int.Parse(StartIPParts[2]) + 255 - (int.Parse(NetmaskParts[2]))) +"." + (int.Parse(StartIPParts[3]) + 255 - (int.Parse(NetmaskParts[3])));
	    System.Console.WriteLine("StartIP: " + StartIP);
	    System.Console.WriteLine("EndIP : " + EndIP);
	    String ItemIP, ItemMAC, ItemName;
	    for (int o0 = int.Parse(StartIP.Split('.')[0]); o0 <= int.Parse(EndIP.Split('.')[0]); o0++)
		for (int o1 = int.Parse(StartIP.Split('.')[1]); o1 <= int.Parse(EndIP.Split('.')[1]); o1++)
		    for (int o2 = int.Parse(StartIP.Split('.')[2]); o2 <= int.Parse(EndIP.Split('.')[2]); o2++)
			for (int o3 = int.Parse(StartIP.Split('.')[3]); o3 <= int.Parse(EndIP.Split('.')[3]); o3++) {
			    if ((o3 == 0) || (o3 == 255))
				continue;
			    String MAC = GetMacFromIP(IPAddress.Parse(o0 + "." + o1 + "." + o2 + "." + o3));
			    if (MAC == "00:00:00:00:00:00")
				continue;
			    ItemIP = o0 + "." + o1 + "." + o2 + "." + o3;
			    ItemMAC = GetMacFromIP(IPAddress.Parse(o0 + "." + o1 + "." + o2 + "." + o3));
			    String[]Item = new String[2];
			    Item[0] = ItemMAC;
			    Item[1] = ItemIP;																																/** You can add Item[] to any collection */
			    Console.WriteLine(Item[0] + " --> " + Item[1]);
			}
	}
    }
    System.Console.WriteLine("Scan Ended");
}

[System.Runtime.InteropServices.DllImport("Iphlpapi.dll", EntryPoint = "SendARP")]
internal extern static Int32 SendArp(Int32 destIpAddress, Int32 srcIpAddress, byte[] macAddress, ref Int32 macAddressLength);

public static String GetMacFromIP(System.Net.IPAddress IP)
{
if (IP.AddressFamily != AddressFamily.InterNetwork)
throw new ArgumentException("suppoerts just IPv4 addresses");

Int32 addrInt = IpToInt(IP);
Int32 srcAddrInt = IpToInt(IP);

byte[] mac = new byte[6]; // 48 bit
int length = mac.Length;
int reply = SendArp(addrInt, srcAddrInt, mac, ref length);

String rawMac = new System.Net.NetworkInformation.PhysicalAddress(mac).ToString();
String newMac = Regex.Replace(rawMac, "(..)(..)(..)(..)(..)(..)", "$1:$2:$3:$4:$5:$6");

return newMac;
}

private static Int32 IpToInt(System.Net.IPAddress IP)
{
byte[] bytes = IP.GetAddressBytes();
return BitConverter.ToInt32(bytes, 0);
}
Share
  • Can You send a file of the source. It's incomplete here.

  • Hi Ray, sorry I don't have the source anymore (It's an old Hard drive who died unexpectedly two years go)
    But if I remember correctly, this code should be complete. What does not work for you?

  • Selcuk

    Can You send a file of the source. It's incomplete here.

  • Sorry, as I stated before the original project was on a hard drive which died.
    What do you think is missing?

  • Berry

    Can You send a file of the source. It's incomplete here.

  • Chris

    I am assuming that what the others were referring to was:

    EndIP = (int.Parse(IPParts[0]) &amp;amp; (int.Parse(NetmaskParts[0]))) + "." + (int.Parse(IPParts[1]) &amp;amp; (int.Parse(NetmaskParts[1]))) + "." +
    (int.Parse(IPParts[2]) &amp;amp; (int.Parse(NetmaskParts[2]))) + "." +
    (int.Parse(IPParts[3]) &amp;amp; (int.Parse(NetmaskParts[3])));

    as this is the only part of the code that has and error... "amp" does not exist and "&amp;amp;" is not a valid statement. What I believe was meant here is:

    EndIP = (int.Parse(StartIPParts[0]) + 255 - (int.Parse(NetmaskParts[0]))) + "." +
    (int.Parse(StartIPParts[1]) + 255 - (int.Parse(NetmaskParts[1]))) + "." +
    (int.Parse(StartIPParts[2]) + 255 - (int.Parse(NetmaskParts[2]))) + "." +
    (int.Parse(StartIPParts[3]) + 255 - (int.Parse(NetmaskParts[3])));

  • Cheers Chris,
    Somewhere along the way the code was converted to HTML tags 🙂
    I will fix the post

  • Manoel

    Hi,

    I tried using your code, but I've got an issue at the StartIP = (int.Parse(IPParts[0]) & (int.Parse(NetmaskParts[0]))) + "." + (int.Parse(IPParts[1]) & (int.Parse(NetmaskParts[1]))) + "." + (int.Parse(IPParts[2]) & (int.Parse(NetmaskParts[2]))) + "." +(int.Parse(IPParts[3]) & (int.Parse(NetmaskParts[3]))); line, it throws me an error about an incorrect format... Do you know what may be at cause?

    Thanks a lot

  • I have updated the StartScan method from an old version I've found
    Please see if it works

    Unfortunately I do not have Visual Studio here to test it myself