43

I have a shell script which uses etherwake to wake up a machine on my local network. After the machine is awake, I'm not sure of the IP address.

While trying to answer my own question I came up with:

ip=$(ping -c 1 hostname | head -1 | awk '{print $3}' | sed 's/[()]//g')

This solution stipulates that I know the hostname of the remote machine, which isn't so onerous.

Is there a way to get the IP if all I know is the MAC address?

ddoxey
  • 2,013
  • 1
  • 18
  • 25
  • 1
    if you know the host name, resolve it's ip, the same way you'd resolve any other host name. And to note, the ping command first calls gethostbyname in it's code, to resolve the ip of the hostname. – johnathan Nov 25 '12 at 16:21
  • You can do a RARP if you are on the same switch/hub/crossover cabal as the system with the known MAC address – Thomas M. DuBuisson Nov 25 '12 at 16:42
  • @ahmad : It looks like arping is a convenient way to get MAC for a known IP. I'm not seeing that it can work the other way. – ddoxey Nov 25 '12 at 17:26
  • @johnathon : Pursuing this question has led me to the conclusion that knowing the hostname can lead to everything else. gethostip -- hostname => IP arping -- hostname => IP and MAC – ddoxey Nov 25 '12 at 17:30
  • possible duplicate of [resolving mac address for IP](http://stackoverflow.com/questions/4480689/resolving-mac-address-for-ip) – Palec Feb 26 '14 at 05:29
  • An other option is to configure the router to reverve a specific ip address for that mac address. That's how I solved it. – user42723 Nov 19 '16 at 17:19

7 Answers7

47

I don't think there is a single command to do this. One hack would be to do a ping scan or a broadcast ping on the subnet and then query the arp table for the IP address of the MAC address. Obviously not an ideal solution. Example:

nmap -sP 192.168.1.0/24 >/dev/null && arp -an | grep <mac address here> | awk '{print $2}' | sed 's/[()]//g'

Here nmap will do a ping scan and populate your arp cache. Once the scan is done, the arp command can be used to print the arp table and then you pull out the IP address with grep/awk. You could try replacing nmap with a broadcast ping, but that probably isn't as reliable.

Neal
  • 6,722
  • 4
  • 38
  • 31
  • This achieves what I set out to do. Thanks! After all of the above, I'm thinking it's not unreasonable that my program just use the remote machine's hostname. – ddoxey Nov 25 '12 at 17:36
  • 2
    When you have a very large network, e.g. /16 subnet this takes too long :( – Mustafa May 19 '15 at 20:32
  • 1
    Doens't work for me. `arp -an` outputs just 4 some random addresses, and `nmap ...` doesn't change that. – Michael Pankov Dec 15 '16 at 11:49
  • 1
    Why not just use arp alone? For me ip=$(arp -a | grep $mac | awk '{print $2}' | sed 's/[()]//g') works. – Thomas Devoogdt Oct 01 '17 at 17:53
  • 3
    @ThomasDevoogdt , sometimes (depending on your network traffic) the ARP cache is not populated enough, and does not include the MAC address you are searching for. – Sopalajo de Arrierez Jan 19 '18 at 20:45
  • How should I run this if I only know `192.168`? is it `192.168.0.0/255/24`? – m4l490n Jan 31 '20 at 18:48
  • In case someone else stumbles upon this, you could try do a broadcast ping i.e. in linux either: ping -c 1 -w 1 -b 192.168.x.255 OR ping -c 1 -w 1 -b -I 255.255.255.255 Then wait a few seconds to check the arp table – Mike Jan 17 '22 at 16:27
37

I would simply use

ip neighbor | grep -i "00:1E:C9:56:3C:8E" | cut -d" " -f1
jdhildeb
  • 3,322
  • 3
  • 17
  • 25
hanoo
  • 4,175
  • 2
  • 26
  • 19
  • 1
    This worked last night, but not today. What? I had to run `nmap -sP xxx.xxx.xxx.0/24` before this command, then it worked again – Rodney Salcedo Mar 02 '17 at 14:01
  • 5
    I think it just checks the ARP cache. – Maciej Swic Apr 16 '17 at 16:32
  • 1
    This is the right way in a modern GNU/Linux box. Further info: [`man ip-neighbour`](http://man7.org/linux/man-pages/man8/ip-neighbour.8.html) – caligari Jul 13 '17 at 15:12
  • 1
    super, but remember the MAC is case sensitive (gentoo) – DnD Jan 31 '19 at 16:14
  • @caligari that doesn't even show the complete list. There are a couple of IPs that are not listed and I'm absolutely sure they are there. – m4l490n Jan 31 '20 at 17:00
  • @DnD use ```grep -i``` (Please, @hanoo Can you improve the answer with insensitive grepping?) – caligari Feb 04 '20 at 13:14
  • @m4l490n man page says _The IPv4 neighbour table is also known by another name - the ARP table._ Probably, missing hosts are not in the ARP table: try to send a packet (ping?) before the command. – caligari Feb 04 '20 at 13:18
14

The other methods presented here were unreliable, e.g. the output of ip neighbor did not always contain the most recent state, so I ended up re-scanning the network using arp-scan, and hence I simply used the output of the scanning to obtain the IP address for a given MAC address.

For scanning a single network interface, simply use this:

arp-scan -q -l --interface en4 2>/dev/null | grep "00:1E:C9:56:3C:8E" | cut -d$'\t' -f1

The following command scans multiple network interfaces at once:

{ arp-scan -q -l --interface en0 2>/dev/null & arp-scan -q -l --interface en4 2>/dev/null } | grep "00:1E:C9:56:3C:8E" | cut -d$'\t' -f1
Lenar Hoyt
  • 5,971
  • 6
  • 49
  • 59
11

You could try the arp command and grep by mac address

arp -a | grep "00:00:00:00:00:00"

(replace with your own mac addr)

dclaudiud
  • 324
  • 3
  • 10
5

I know is old, but the simplest way in linux is:

arp -a | grep "00:1E:C9:56:3C:8E"

The point of this is to ignore if is connected in one or another network meanwhile each device can see each other.

VicHaunter
  • 82
  • 1
  • 4
2

I wrote a python module that can do this:

>>> from ethip import ethip
>>> print ethip.getip('00:1E:C9:56:3C:8E', '10.5.42.255')
10.5.42.3

I just makes rapid arp requests to find the ip, then caches what it finds. The code is on github.

David Mulder
  • 7,595
  • 11
  • 45
  • 61
  • `ethip.getip('00:1E:C9:56:3C:8E', '10.5.42.255')` gives an `EOFError` with no information on the ARP. Once ARP has the details of the device under question, `ethip.getip()` works fine. Is there a way to get the ip address without having to update the ARP table everytime – Blue Feb 27 '18 at 08:43
  • @Blue it has to be run with root privileges. You need root to send an arp request, afaik – David Mulder Apr 03 '18 at 19:49
  • python2 and no longer maintained – MaKaNu Jul 21 '23 at 09:19
1

Neal's answer takes indeed too long. I had to get it work with a 60k+ IPs range. The trick to make this work is to check arp table after each ping. This also fixes the root problem : no need. I did it in Java (see threadedScan() here) because I was on windows and needed a solution which wouldn't spawn thousands of cmd prompts while trying to ping with start command. And it works faster (~10 sec for my 60k range) with a fixedThreadPool.

eaz
  • 61
  • 3
  • 1
    I didn't downvote, but probably because 60k+ in a single broadcast domain is a bad idea. – fsp Aug 15 '17 at 19:39