Ping network and get mac addres - c++

I'm a starting C/C++ programmer.
What I want is the following thing:
Start program, starts to ping whole network and saves the addresses that where active. When done, get mac address from ip addresses that where stored before, and save them.
When done, loop trough the mac address list, and find 1 mac adress, when found, shout around that he found it.
Something like that does I want to make.
I've Googled a lot, but nothing realy helped me.
So my question, what do I need (which libraries, which statements), so I can program this.
On note, my OS is at the moment Windows, but I want to make it compatible with Linux in the future also.

Use the arp tool on the commandline eg arp -a 192.168.0.100
From c++ it depends on your OS, on Windows it's SendArp()
To scan for all machines on the lan use nmap - see How do I get a list of the active IP-addresses, MAC-addresses and NetBIOS names on the LAN?

Related

How can you determine if a network adapter is wired or wireless with WinPCap?

I'm writing a program that uses winpcap to capture some specific network traffic that is sent out by our switches.
However, wireless devices will never receive those packet so I'm trying to figure out how to determine if a network adapter is wireless or wired (so that I can then skip capturing on the wireless adapters altogether).
My first thought is to check the medium of the interface chosen (currently chosen based on the IP address of that adapter - the logic is that if it has an IP address, it is connected). The problem is, is that pcap_datalink() will return DLT_EN10MB, whether its wired or wireless.
The next thought was to try pcap_can_set_rfmon(), which should tell me if the device cannot be set to monitoring mode (and therefore if it is or isn't wired). However, I seem to get a 2019 linking error when I try to use this, which seems to be supposedly to do with the function not being supported on Windows without Airpcap?
I don't really see what else to try but it would be great if someone had any pointers. I'm wondering how difficult and convoluted it would end up becoming if I had to start using NDIS to determine what each adapter on a system is and then match that up to the device names used by WinPCap.. surely this is something I could keep in-house with lib/WinPCap?
Thanks!
I have a solution of sorts, just for Windows systems.
For an adapter that I want to select, based on the network it is connected to, I can compare the IP address associated with that adapter with each of the IP addresses in objects generated by GetAdaptersInfo. If they match, then I can see whether or not the "Type" on that same object is ethernet.
if ((pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET) && (WINVER > _WIN32_WINNT_WS03))
{
}
I also check the Windows version; since it is only from Vista (Winver 6+) onwards that IF_TYPE_IEEE80211 is returned in the adapter is wireless.
It doesn't use WinPCap, but then again I'm not sure its possible to. Since I already am using these Windows libraries elsewhere, I figured that this is a platform-specific compromise I'll make. Hopefully that helps someone else one day!

How to iterate through com ports and print to console on Linux & C++?

I feel like this should be rather easy, but it continues to vex me, so here it is. I've been trying to find a simple solution to iterate through the available UART serial ports on linux (I'm running the most recent version of Manjaro Linux) and then printing these to the console. Yet, all of the solutions I've found thus far have been incredibly convoluted or they end up throwing a bunch of errors that I can'at figure out when I test them.
So, I've resorted to coming back here to see if anybody else has any ideas. On Windows, there is a GetPortNames() of Windows' System::IO::Ports, maybe a similar API call would be the most ideal.
Update:
So after receiving an answer and using that information to learn a bit more about interacting with serial ports on linux, I eventually ran across a good way to accomplish this effect of iterating through the available ports. It's not quite as simple as a one-line command, but it works so it's fine with me. I found this method of iteration/sorting through the /sys/class/tty directory as an answer to another question (the author of the code that I used is named Søren Holm), and you can look at that here.
Two simple possibilities:
Serial ports on linux are character device files, you can see them on /dev/ttyS*. Serial ports created by an usb device are in /dev/ttyUSB*. This reduces your problem to a dirent iteration.
There is also a thing named sysfs, it is essentially a runtime, non-persistant, kernel-internal registry which is exported to the user space via a virtual filesystem. Normally it is mounted below /sys. Below /sys/bus/serio/devices you can find the devices.

How to convert a MAC address to the corresponding IP address?

I am looking for an easy way to convert a MAC address to the corresponding IP address in a local network. In my case, there are only two devices: a very normal PC (192.168.0.1) and a scientific instrument which has an arbitrary IP address (192.168.0.xxx) hard coded in its ROM. The PC and the instrument are directly connected over a UDP socket with a CAT5 cable.
I know the MAC address of the instrument, but please assume that its IP address is unknown. I would like to write a C/C++ application which talks with the instrument using a socket connection. But I need to know the IP address before opening a socket (WinSock on Windows, sys/socket on OS X and Linux).
Currently I use a very dirty way as shown below.
Execute ping command ping 192.168.0.2 (NOTE: the instrument does not respond to ping)
Repeat this from 192.168.0.2 to 192.168.0.255
Execute arp -a to print a list of IP and MAC addresses
Find the known MAC address and the corresponding IP address from the list
I would like to know how to retrieve the IP address in a more sophisticated way. It will be very nice if I can use the same method on Mac, Linux and Windows machines.
As far as I know, I have to broadcast a ARP packet to the network in order to retrieve a MAC address from a known IP address. But I could not find a way to get an IP address from a MAC address.
There's no good, generic solution for this as it is the reverse of intended behavior. Lower level protocols are not supposed to need to be aware of higher layer ones, so operations at the MAC layer don't have any good way of finding out about IP addresses. And then you get into the situation you're in now. So you can either employ a hack like the code you already have, or you can tackle this from a different direction. Is there any non-code way to determine the IP address of the device before hand? Such as setting it explicitly or putting it in a configuration file for your app. Alternatively, can you have the device send out spurious ARP requests? The PC should update its ARP cache based off of incoming requests as well as responses to requests it made.
We had to do this a while back, but I don't think we got it working properly.
I don't have the API calls off-hand, but they're easy to find in the Windows API. That's what we used, so our solution wouldn't be portable to non-Windows systems.
In our case, we ran into the same hurdle--no easy translation. What we ended up having to do was get a list of all the NICs available, and then loop through each one trying to match our given MAC address against the MAC address obtained from the NIC structure.
Once we found a match, we looked up the IP address given to the NIC structure.
We kept on going to see if we found any other matches in order to log an error. It's a good thing we did, because I believe we did find it multiple times, and it wasn't due to a MAC address being cloned.
That's when we learned that this would be an even harder problem, and we decided to abandon the whole thing and stick to just IP addresses.
How about try the system command arp within c++
system("arp");
This gives you a IP-MAC translation table.
few days ago I was also facing this issue but after many struggle I got its solution below
How MAC to IP address converter tool works?
This MAC address converter can convert MAC address to IPv4 IP Address and convert MAC address to IPv6 IP Address, these internet protocol Addresses are very common to use. It takes MAC Address as input string and generates a query against given MAC to IP address and MAC conversion option like to MAC to IPV6 or MAC to IPV4 or both for MAC address conversion together. After this MAC conversion you can also revert MAC to IP conversion changes by using IPv6 to IPv4. Query generates an output response according to selected options.If you insert any invalid input produces an invalid input message response

Linux Equivalent of MachineGuid

I have program that needs OS installation fingerprint like one in MSW stored at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid
In Microsoft Windows I have it ready for me but I cannot find equivalent for Linux. Is there anything close to this in Linux? I will not have root access so anything like dmidecode -s system-uuid becomes out of the question.
An example will be nice but no necessary.
One possibility would be to read /etc/ssh/ssh_host_{d,r}sa_key.pub, which are readable by all, and are randomly generated during installation.
Obviously the problem is that those files may not exist at all, if there is no SSH (server) installed. They are also often copied from an older installation.
I believe MAC addresses are not a good choice for identifying a machine. There are many USB dongles which may be plugged into a PC to provide a mobile/3G/H+/etc. network interface, so while such a dongle is plugged into the machine, it will have a different id derived from available network interface MAC addresses.
Is /etc/machine-id (/var/lib/dbus/machine-id) available on your target system?
see: http://man7.org/linux/man-pages/man5/machine-id.5.html
see: http://0pointer.de/blog/projects/ids.html
The canonical Unix'y answer is the Host ID, but in practice, this often ends up falling back on a hash of the IP address…
#include <unistd.h>
long gethostid(void);
int sethostid(long hostid);
DESCRIPTION
gethostid() and sethostid() respectively get or set a unique 32-bit identifier for
the current machine. The 32-bit identifier is intended to be unique among all UNIX
systems in existence. This normally resembles the Internet address for the local
machine, as returned by gethostbyname(3), and thus usually never needs to be set.
NOTES
In the glibc implementation, the hostid is stored in the file /etc/hostid. (In glibc
versions before 2.2, the file /var/adm/hostid was used.)
In the glibc implementation, if gethostid() cannot open the file containing the host
ID, then it obtains the hostname using gethostname(2), passes that hostname to geth‐
ostbyname_r(3) in order to obtain the host's IPv4 address, and returns a value
obtained by bit-twiddling the IPv4 address. (This value may not be unique.)
I assume you're trying to do this because you want to "lock" the software to a specific piece of hardware?
One option is to use the MAC address of a network interface to identify the current machine. The MAC address is fairly easy to get at, see this Stackoverflow question.
This nicely works around issues with changing IPs etc as the MAC address of an interface is much less likely to change unless someone replaces the network card.

How to get hardware MAC address on Windows

I'm playing around with retrieving the MAC address from the NIC - there are a variety of ways to get it, this article covers the most common:
http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5451
I'm currently using the GetAdaptersInfo method, which seems the most bulletproof, but if the MAC address has been set via the registry:
http://www.mydigitallife.info/2008/06/30/how-to-change-or-spoof-mac-address-in-windows-xp-vista-server-20032008-mac-os-x-unix-and-linux/
Then it reports the MAC address that it has been changed to. The only way I've found to actually get the true MAC is to remove the registry entry, restart the NIC, get the MAC via GetAdaptersInfo, then replace the registry entry, and restart the NIC. While it gets the job done, it's hardly transparent to the user.
Is there any other methods that anyone is familiar with, that will return the hardware MAC regardless of what the registry is set to? Ideally I'd like a solution that works on XP on up.
Thanks in advance!
My guess is that in the linked CodeGuru article, the Miniport solution is likely to overcome the problem you describe, albeit painful to implement. The reason I think this is that I have used the GetAdaptersInfo solution myself in the past, and noticed that the MAC address will change without reboot when an adapter is added, e.g. a Bluetooth adapter providing PAN services.
Perhaps rather than rebooting after changing the registry setting, you could try stopping and restarting the relevent network services. You could easily check this manually prior to looking for a programmatic solution.
(n.b. the above is all guess work. If you try it and it works, perhaps add a post for those trying to do the same in future).
Parse the output of ipconfig /all
You can use WMI to enumerate the Win32_NetworkAdapter instances and look at the MACAddress property. The main issue with this technique is finding the appropriate adapter instance if you have multiple active adapters installed, e.g. on a laptop which also has a wireless connection.