Jason
Jason

Reputation: 821

Mac Scanning Code only grabs 1 IP Address in a loop

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

namespace macscantest
{
    class Program
    {

        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);
        }

        static void Main(string[] args)
        {
            StartScan();
        }
    }
}

When the code runs it will pull one IP address and that is the machine's and will stop. It does not seem to be scanning the full network despite getting the correct IP info.

enter image description here

Not entirely sure where I am going wrong with this.

My target build is for .NET 2.0 if that means anything.

At this location:

String MAC = GetMacFromIP(IPAddress.Parse(o0 + "." + o1 + "." + o2 + "." + o3));
                                    if (MAC == "00:00:00:00:00:00")
                                        continue;

Despite the IP address being a real device, the mac is coming out as all 0's/

Upvotes: 0

Views: 125

Answers (1)

mcq8
mcq8

Reputation: 247

The problem is in the SendArp(addrInt, srcAddrInt, mac, ref length); where addrInt and srcAddrInt the destination ip. You have to set the ip op the interface you want to use as source address or 0 to send the arp request on all interfaces (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366358(v=vs.85).aspx).

Upvotes: 1

Related Questions