Get local IP Address from a known MAC Address in Python? - python

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.

Related

How do you get a mac address from an IP address on your network?

Having issues with a get_mac function i created below, which takes an IP Address and finds its mac address, returning it or None.
The actual python function is:
def get_mac(ip_addr):
"get_mac is used to obtain the mac address of the target ip."
print "Getting Mac for: %s" % ip_addr
responses, unanswered = srp(Ether(dst="de:ad:be:ef:ca:fe")/ARP(pdst=ip_addr),timeout=2,retry=10)
for s,r in responses:
return r[Ether].src
return None
Im thinking that there may be a better way to do this. This was taken out of the Black Hat Python book, and im leveraging the imports:
from scapy.all import *
from scapy.base_classes import Gen, SetGen
import scapy.plist as plist
from scapy.utils import PcapReader
from scapy.data import MTU, ETH_P_ARP
import os
import sys
import threading
import signal
for my entire file file I have been working ith. I was working on creating a custom tool for a very fine tuned purpose. I was running it against my buddy to by way of ipconfig told me his IP was 192.168.0.20 so when running against that, i could see the console outputting this information.
....
Begin emission:
Finished to send 1 packets.
Received 12 packets, got 0 answers, remaining 1 packets
....
12 times and then printed what i told it to since it returned none.
! Failed to find Target Mac
Is this the right course of action? Did my buddy send me the wrong IP address? I think i saw him give me the ipv4 in ipconfig
I guess iam curious if there is a better way then the srp() function i ended up calling.
The base sample I was working with was page 52 of BlackhatPython called: ARP Cache Poisoning via Scapy.
Assuming that you're just trying to implement an ARP request, then the request should be sent to the MAC broadcast address (FF-FF-FF-FF-FF-FF). You should be filling in your own NIC's MAC address as the source address, both in the Ethernet header, and as the ARP sender-MAC address.
The way ARP typically works is that a broadcast message is sent to the local network, in essence saying "Hey everybody, who has IP address N.N.N.N? Tell me <my MAC address>." It typically also includes the sender's IP address, which in effect says "And oh, by the way, my IP address is M.M.M.M."
The response is then usually sent via unicast back to the requester which is why you need to fill in your own MAC as the sender address: so that you get the response.
There are other ARP usages wherein the "who has?" part is a dummy, and the "oh, by the way, my address is..." is the main goal -- that's known as gratuitous ARP since it's often sent without a preceding request and is essentially just announcing the sender's own IP/MAC association.
(It doesn't appear that you meant to ask about ARP cache poisoning, but that's essentially just lying about the "oh, by the way" clause. Either with the wrong MAC address or a completely bogus one.)
The scapy srp function is fine for doing this. Probably the easiest way to implement it in python.

Python - How to convert a MAC address into an IP address [duplicate]

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

get IP adresses of my local network

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.

MAC Address from IP across 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")

How to get the LAN IP that a socket is sending (linux)

I need some code to get the address of the socket i just created (to filter out packets originating from localhost on a multicast network)
this:
socket.gethostbyname(socket.gethostname())
works on mac but it returns only the localhost IP in linux... is there anyway to get the LAN address
thanks
--edit--
is it possible to get it from the socket settings itself, like, the OS has to select a LAN IP to send on... can i play on getsockopt(... IP_MULTICAST_IF...) i dont know exactly how to use this though...?
--- edit ---
SOLVED!
send_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
putting this on the send socket eliminated packet echos to the host sending them, which eliminates the need for the program to know which IP the OS has selected to send.
yay!
Looks like you're looking for the getsockname method of socket objects.
quick answer - socket.getpeername() (provided that socket is a socket object, not a module)
(playing around in python/ipython/idle/... interactive shell is very helpful)
.. or if I read you question carefully, maybe socket.getsockname() :)

Categories

Resources