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
Related
I am running a Python Script on the Raspberry Pi in order to get measured data out of a Smart Plug. In my script I need to write the IP-Address of the Smart Plug so that I can retrieve the data it was measured. The problem is that I need to be able to take the Smart Plug to different places without having to hard code its new local IP-Address every time.
I have the MAC Address so I am hoping there is an "easy" way to add a couple lines of code and retrieve the local IP-Address from the MAC (?) in the Python Script. Thanks!
This can be achieve using arp command in the subprocess module. Here is code. Checked in windows.
import subprocess
cmd = 'arp -a | findstr "ff-ff-ff-ff-ff-ff" '
returned_output = subprocess.check_output((cmd),shell=True,stderr=subprocess.STDOUT)
print(returned_output)
parse=str(returned_output).split(' ',1)
ip=parse[1].split(' ')
print(ip[1])
What you're describing can be accomplished by crafting an ARP packet to get that info.
Generally something like:
from scapy.all import srp, Ether, ARP ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"),timeout=2)
ip = pkt[ARP].psrc
The local ip address is not based on the MAC address. The router uses DHCP to give the devises an ip address. So there is no way to tell the router which IP he must give you other than changing the settings.
I would rather try to broadcast the ip and on the raspberry listen on the broadcast channel for the message you are looking for.
In documentation we can read:
"The IP of the outgoing IP address to use for the performing the request."
That is not clear for me. Anyone can explain with more details what is the purpose of bindaddress ?
The computer where Scrapy is running might have multiple network connections, each with their own unique IP network address (or addresses, plural). For example, a laptop might have a WiFi connection and a wired Ethernet connection. A larger server-class system might have several Ethernet connections. Even a system that has a single network connection might have multiple IP addresses, some for IPv4 and others for IPv6.
The bindaddress option can be used to tell Scrapy which one of those local IP addresses should be used as the source address on its outgoing requests.
If you don't specify which local address you want Scrapy to use, then Scrapy will let the system choose the address. That choice is usually the local address that the system thinks is "closest" to the destination address of the request. This would be the usual situation. Unless you have a particular need to use a specific source address, there's no reason to use the bindaddress option.
How do you lookup the local hostname from an IPv6 address in Python?
I'm trying to diagnose network bandwidth hogs, and I'm using Wireshark to find which IPv6 addresses are using the most bandwidth, but it doesn't include any hostsnames, so I'm left with a CSV of IPv6 addresses and total bytes transmitted.
Note, I'm not talking about converting a generic IP to domain, since that only works for DNS, not your local network's hostnames.
The only command line tool I know for doing this is:
sudo nmap -sn 192.168.1.0/24
but that doesn't list IPv6 addresses.
This is what I found looking online, I'm sorry but i think that what you are lookin at isn't possible.
From WireShark Q&A:
What you're looking at are probably neighbor discovery packets, which
are sent to a special multicast address called "solicited node
multicast".
It's basically the replacement mechanism for ARP, which is not used
for IPv6 anymore.
Usually, if you need to find out where something is coming from you
should try to determine the MAC address of the source, and then log in
to your switches to find the port where that MAC address is connected.
There should be a command that will show you the MAC address table of
the switch. If you can find a port where only the MAC address in
question is listed you need to follow the cable from that port to the
device.
If you have more than one MAC address listed for a port it is usually
a connection to another switch. In that case you need to log in to the
switch it connects to and repeat your search.
I am working on a GUI program to command power supplies by Ethernet.
I have the DHCP of my computer activated, therefore I guess that the IP adresses of my power supplies are fixed by my computer.
I would like to know the IP addresses of my power supplies, in order to communicate with them through the TCP/IP protocol, using Python.
For the moment, I use a program called LXI discovery tools, and while I run it, the Window command arp -a command gives me the IP adresses of my power supplies.
The problem is that I need to run this LXI program. Is it obligatory?
Owing to the DCHP, my computer is the one which sets the IP addresses, therefore isn't there a way to get those addresses more easily?
Moreover, is the Python socket library able to help me?
Finally I solved my problem, using statique IP addresses. Therefore I know them and I don't need anymore to "scan" my network.
I hope you're all well.
I'm wondering if you could help me or point me in the right direction. I'm currently working on a project that centers around network management. Due to severe time constraints where possible I'm using opensource code. The issue I'm having is that part of the project requires me to be able to capture the MAC addresses of all of the devices that are connected to the network.
My knowledge of network orientated programming is limited as I have been working in other areas of software engineering for the past 4 years. The approach I have taken is to use nmap as a basis to get the ip address and other information I need. The MAC address is not included in the nmap out put and from what I have read it seems to be a bit flakey. (i could be wrong).
Therefore I have tried to do this in a two stage approach, firstly I get the data including ip address from nmap which works fine. My next step and the bit I'm having difficulty with is I ping the ip address (from within my python program) which works. But how do I get the MAC Address from the IP address? I initially thought ping the ip and grab the MAC from the ARP but I think that will only work if the IP address is on the same subnet. to compound the problem on deployment there could be up to 5000 computers on the network that needs to be logged. To show you my python ping approach this is the code:
import pdb, os
import subprocess
import re
from subprocess import Popen, PIPE
# This will only work within the netmask of the machine the program is running on cross router MACs will be lost
ip ="192.168.0.4"
#PING to place target into system's ARP cache
process = subprocess.Popen(["ping", "-c","4", ip], stdout=subprocess.PIPE)
process.wait()
result = process.stdout.read()
print(result)
#MAC address from IP
pid = Popen(["arp", "-n", ip], stdout=PIPE)
s = pid.communicate()[0]
# [a-fA-F0-9] = find any character A-F, upper and lower case, as well as any number
# [a-fA-F0-9]{2} = find that twice in a row
# [a-fA-F0-9]{2}[:|\-] = followed by either a ?:? or a ?-? character (the backslash escapes the hyphen, since the # hyphen itself is a valid metacharacter for that type of expression; this tells the regex to look for the hyphen character, and ignore its role as an operator in this piece of the expression)
# [a-fA-F0-9]{2}[:|\-]? = make that final ?:? or ?-? character optional; since the last pair of characters won't be followed by anything, and we want them to be included, too; that's a chunk of 2 or 3 characters, so far
# ([a-fA-F0-9]{2}[:|\-]?){6} = find this type of chunk 6 times in a row
mac = re.search(r"([a-fA-F0-9]{2}[:|\-]?){6}", s).groups()[0] #LINUX VERSION ARP
mac = re.search(r"(([a-f\d]{1,2}\:){5}[a-f\d]{1,2})", s).groups()[0] #MAC VERSION ARP
print(mac)
I have looked for some information but what I have found seems a bit vague. If you know of any ideas or avenues of research that may help me I would be greatful
Cheers
Chris
You can't directly get the MAC address of a machine outside your subnet.
A common strategy for network management applications is to query machines that do have this information, such as the routers and switches connecting the machines, using SNMP. Routers have arp tables for the subnets to which they are directly connected (as they need this to do their job), and this information can be acquired from the router.
The answers to this question might help with finding python library code to help in this endeavor.
You cannot get the original MAC address of the host if you are not connected to the same subnet - you would just get the MAC address of the last router.
The only way to get all MAC addresses would be to setup a server to catch them in each subnet, but this seems to me a bit crazy idea. Note also that nowadays it is very easy to spoof the MAC address, and it is not reliable at all.
Over all, I think you should use a different approach; for instance, there are plenty of network inventory systems, you could just use one of them, and interface with it.
You can use python scapy module to get mac address
from scapy.all import *
def get_mac(ip_address):
responses,unanswered = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip_address),timeout=2,retry=10)
# return the MAC address from a response
for s,r in responses:
return r[Ether].src
return None
get_mac("192.168.31.14")