Jump to content
ErikT

Network scan in Delphi (Windows), get MAC addresses

Recommended Posts

Hi,

 

I am writing a piece of software, that needs to find specific devices on a LAN. The functionality I need is more or less a scaled-down version of "Advanced IP Scanner", or similar software.

My intention is to connect to all devices in a subnet, one at a time, and get the MAC address from each device. I can determine if a device is of interest based on the 36 most significant bits of the MAC address.

 

Now, how do I do that? I have found a number of examples that give me the MAC address of my own computer, such as this:

And other examples that don't tell much about what they actually do, such as this: https://www.swissdelphicenter.ch/en/showcode.php?id=651

 

Does anyone around here know how to get the MAC address of devices on a LAN in Delphi?

Share this post


Link to post

Update: I found another example, which I actually got working. So now I can give a function an IP address, and get a MAC address in return.

So now my task is boiled down to figuring out if each address exixts on the LAN, or not.

 

When I get both things working, I'll post the code here for others to use.

Share this post


Link to post

I suggest searching using a search engine. You will find several results. The most common approach is to calculate the IP range for your LAN using the computer's IP address and subnet mask. Once you know the range of IP addresses for the LAN, ping each IP address. For better performance, use multiple threads to ping several addresses simultaneously.

 

Note that just because ping does not receive a response does not mean that there is not a device at that address. Not all devices respond to ping requests.

 

If you want to "search deeper", you could scan a port range for each IP address. Although that would take significantly longer.

 

If you are looking for a particular device or application, you may be able to find out what it uses for network discovery, such as Apple's Bonjour. If you are wanting to discover your own applications running on other machines within the network, take a look at UDP broadcasts (servers and listeners).

Share this post


Link to post

Hello @JonRobertson

 

Yes, that is exactly what I am doing. I have implemented the ping method, which nearly works. The devices I am searching for do respond to a ping, so that is no issue. They are not computers, by the way.

 

At the moment I'm struggling with the Indy Ping procedure, that apparently has a problem. After running a seemingly random number of times (e.g. 20), it raises an exception: Socket Error #10040 Message too long. This seems to be a known issue with Indy Ping, and I am searching for a functioning work-around for it.

After raising the exception, I can't get Ping going again without restarting the application. Will continue the search for a fix tomorrow.

Share this post


Link to post
2 minutes ago, ErikT said:

At the moment I'm struggling with the Indy Ping procedure, that apparently has a problem.

You could try another set of Internet components, such as ICS. I have not needed low-level Internet functionality for a while. But I used to use ICS quite a lot.

 

Internet Component Suite

 

ICS is available for VCL and FMX. In recent versions of Delphi, it can also be installed via GetIt Package Manager.

Share this post


Link to post

Hi,

 

@ErikT , I would suggest :

1) Make WireShark your close and trusted friend, get familiar with it and use it extensively, depend on its result to diagnose what do you see against what you get.

2) Get familiar with nmap https://nmap.org/ , there is many resources to get you started, it is open source and great tool with many feature, use WireShark to understand its packets and get ideas from it, nmap has many ways (documented and undocumented) to scan an IP and even detect firewall presence on a remote IP. 

Share this post


Link to post

Hello @Kas Ob.

Thank you for your comments.

1) Yes, I do use WireShark, although in this particular case it hasn't helped me a whole lot. No packet stand out, making me believe that the problem with Indy Ping is internal in its code, and not on the network.

2) Thanks, I may have a look at that. However, I find it a bit disconcerting, that the word hack/hackers show up seven times on the first page alone...

Share this post


Link to post

ICS has a new component TIcsNeighbDevices that builds a historic LAN neighbourhood MAC device and IP address table that shows MAC vendor name to help identify devices.   Runs in a thread continually checking for new devices.  ICS can be installed from Getit.

 

To test it, build the ICS Network Tools sample, it's very similar to the excellent Nirsoft Wireless Network Watcher tool I've run continually for a decade to monitor my LAN.

 

Angus

Share this post


Link to post
35 minutes ago, ErikT said:

I find it a bit disconcerting, that the word hack/hackers show up seven times on the first page alone...

Well, we have different meaning for hack/hacker as word, as it is like rubber nowadays and have being used not well defined term, it is not bad at all, it is a word describing ..... Wikipedia explain this way better than me https://en.wikipedia.org/wiki/Hacker

Have heard about hackathons and their sponsors (like Microsoft, Apple, Google....) it is essential process in advancing technology evolution, to invent, share and spread knowledge also critical in security defense. 

Share this post


Link to post

May be you can use the ARP protocol ... finding MAC Add is its function:

 

Uses  WinApi.Winsock2, WinApi.IpHlpApi, WinApi.IpExport;

procedure TForm1.Button1Click(Sender: TObject);
var
  DestIP, SrcIP: IPAddr;
  AddrLen: ULong;
  MacAddr: array[0..5] of byte;
  s: AnsiString;
  i: integer;
begin
  SrcIp := 0;
  s := '192.168.2.10';    //ROTATE IP
  DestIP :=  inet_addr(PAnsiChar(s));
  AddrLen := SizeOf(MacAddr);
  SendARP(DestIP, SrcIP, @MacAddr[0], AddrLen);
  s := ' MacAddress : ';
  if AddrLen > 0 then
    for i := 0 to AddrLen-1 do
    begin
      s := s + IntToHex(MacAddr[i], 2) + '-';
    end;
  SetLength(s, length(s)-1);
  ShowMessage(s);
end;

 

Share this post


Link to post

@DelphiUdIT

Yeah, I'm using ARP to get the MAC address. I hadn't thought about using it to find the actual devices directly. That should be easy to implement.

 

I've got it running using ICS Ping. Isn't as fast as I'd hoped, but does work. I will have a go with the ARP method, as I already have part of the code running.

Share this post


Link to post

@Kas Ob.

Okay, I see that the "hacker" term has mellowed over time. Apparently, I'm a bit old.

Share this post


Link to post
3 hours ago, ErikT said:

Okay, I see that the "hacker" term has mellowed over time. Apparently, I'm a bit old.

I disagree. In my opinion, hack/hacker/hacking has never been a bad thing. Hacking is a terrific way to learn, especially for self-taught individuals such as myself.

 

Sure, people have done a great deal of malice, which is unfortunate. And believing that all hackers are malicious is an unfortunate side effect of the harm caused by others.

Share this post


Link to post
Posted (edited)
4 hours ago, ErikT said:

Apparently, I'm a bit old.

Age is relative. :classic_wink:  Fwiw, I'm 51 and started "hacking" (and learning) BASIC on a Commodore PET in 1981.

Edited by JonRobertson

Share this post


Link to post
10 minutes ago, JonRobertson said:

Fwiw, I'm 51

So am I. I also began with BASIC in the eighties, although I would never call my self a "hacker". My core competences are in hardware and microcontrollers. Not computer programming.

 

I got the ping search running with ICS, although terribly slow. It seems that the timeout won't go below about 450 ms. I had hoped to use about 100 ms, as my devices rarely spend more than 1 ms when responding to a ping. However, it is certainly much better to have something that works slowly, than the faster option that doesn't work.

 

Thank you for the ICS tip. It seems that poeple have been complaining about the Indy Ping problem for more than a decade, and apparently nothing has happened.

Share this post


Link to post
20 hours ago, ErikT said:

At the moment I'm struggling with the Indy Ping procedure, that apparently has a problem. After running a seemingly random number of times (e.g. 20), it raises an exception: Socket Error #10040 Message too long. This seems to be a known issue with Indy Ping, and I am searching for a functioning work-around for it. 

After raising the exception, I can't get Ping going again without restarting the application. Will continue the search for a fix tomorrow.

 

1 hour ago, ErikT said:

It seems that poeple have been complaining about the Indy Ping problem for more than a decade, and apparently nothing has happened.

I'm not aware of those. I have some applications that call PING and TCP alternate, thousands of times a day to various devices (over the Internet), and I have no such error reports.

And they are applications that run for years without ever being turned off.

 

They use TIdICMP (for ping) (WIN32 version) and are multithread applications but all the PINGs are running only from one thread.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×