2

Is there any such thing as a file linking MAC addresses to IP addresses / DNS names for use with wakeonlan on Linux? Something like this:

$ cat /etc/machosts
00:1f:d0:34:e0:ea 192.168.0.5
00:1f:d0:34:a1:06 192.168.0.7
$ cat /etc/hosts
192.168.0.5 mypc
$ wakeonlan mypc

Thanks.

Fela Maslen
  • 1,183
  • 2
  • 11
  • 19

7 Answers7

4

Some minor bash:

$ cat /path/to/machosts
macs[mypc1]=00:1f:d0:34:e0:ea 
macs[mypc2]=00:1f:d0:34:a1:06 

$ cat wakeonlan.sh
#!/bin/bash

. /path/to/machosts

echo wakeonlan ${macs[$1]}

$ ./wakeonlan.sh mypc1
wakeonlan 00:1f:d0:34:a1:06

This uses bash arrays: http://tldp.org/LDP/abs/html/arrays.html

The unix.stackexchange.com site can probably help more with doing this script and the one that processes arp output.

cjc
  • 24,533
  • 2
  • 49
  • 69
3

The etherwake utility (upstream seems to be dead) can read MAC addresses from /etc/ethers (or another kind of ethers database specified in /etc/nsswitch.conf).

Sergey Vlasov
  • 6,088
  • 1
  • 19
  • 30
2

I created my own bash script for it:

#!/bin/bash

die () {
  echo >&2 "$@"
  exit 1
}

# we need one parameter - the hostname or IP address
[ "$#" -eq 1 ] || die "1 argument required, $# provided"

if [[ ! -f "/etc/machosts" ]]; then
  die "Can't find /etc/machosts file!"
fi

host="$1"

# if argument isn't an IPv4 address, try to resolve it
if [[ ! $host =~ ^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$ ]]; then
  echo "Attempting to identify IP from name: $host..."
  host=$(getent ahosts $host | head -n 1 | cut -d" " -f1)
fi

if [[ ! $host =~ ^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$ ]]; then
  die "Invalid hostname"
fi

mac=""

# read /etc/machosts line by line
while read line
do
  if [[ !(${line:0:1} == "#") && ( -n "$line" ) ]]; then
    ip=$(echo $line | cut -d" " -f2)
    addr=$(echo $line | cut -d" " -f1)

    if [[ $ip == $host ]]; then
      mac=$addr
      break
    fi
  fi
done < "/etc/machosts"

if [[ -z $mac ]]; then
  die "No MAC address asociated with that host!"
fi

wakeonlan $mac

exit 0

My /etc/machosts looks like this:

# here the MAC hosts are defined
#
# e.g. 50:e7:24:ab:c0:d3 10.3.12.5

50:e5:49:1a:8c:9c 192.168.0.4
00:1f:d0:34:e0:ea 192.168.0.5
00:25:22:b1:f6:be 192.168.0.6
00:1f:d0:34:a1:06 192.168.0.7
Fela Maslen
  • 1,183
  • 2
  • 11
  • 19
  • 3
    What you're calling "machosts" is called "ethers" on Linux and most UNIXes. The ethers(5) man page on FreeBSD says the hostname (the second field of each line) should match an entry in /etc/hosts, while ethers(5) on Linux says it should be resolvable using DNS or a numeric IP address. – Gerald Combs Aug 08 '12 at 21:39
  • If I do `man ethers` it tells me I should have an /etc/ethers file, but it doesn't exist. The man page seems to come with the net-tools package. – Fela Maslen Aug 08 '12 at 22:36
  • Which OS are you using? Some still include it by default (Red Hat, SUSE) but many don't (Debian, OS X, Solaris). (Just to be clear, you can call the file anything you'd like. It's your system. I'm just pointing out that there's an established name and format for what you're trying to store.) – Gerald Combs Aug 09 '12 at 15:33
  • Ah, okay then. I'm running Debian so that explains it. Might as well keep it as machosts for now, but I'll change it if the need arises. – Fela Maslen Aug 09 '12 at 20:45
  • /etc/ethers is used by the rarp daemon. However rarp support was removed from the linux kernel from version 2.3. A replacement daemon package is available. – hookenz Jan 10 '13 at 02:00
1

"Is there [...] a file linking MAC addresses to IP addresses [...] on Linux?"

Yes, sort of: /proc/net/arp. But of course, that is not a real permanent file.

The standard file for your purpose is /etc/ethers, but you have to create and populate it. Doing it by hand is boring, but writing a command-line to do it for you is fun.

You can either

  • ping all hosts and parse /proc/net/arp (or arp -n if not on Linux),

  • or you can use nmap (sudo apt-get install nmap ?) to scan the local network for you, and give you both the IP and MAC addresses.

The first solution could be something like this :

for i in `seq 1 254`; do
    ip=192.168.1.$i
    if ping -c 1 -w 1 $ip >/dev/null; then
        mac=$(grep "^$ip" /proc/net/arp | awk '{print $4}')
        echo "$mac  $ip"
    fi
done

The nmap solution, which should be faster, could look like this:

sudo nmap -sP -n -oN - 192.168.1.0/24 | \
perl -nle 'if (/ \b ([0-9\.]{7,15}) \b /x) {$ip=$1} elsif (/ ([0-9A-F:]{17}) /i) {print "$1  $ip"}'

To also get the DNS names, you could pipe the output from above through something like

| while read mac ip; do name=$(dig -x $ip +short | grep -v '^;'); [ -n "$name" ] && ip=$name; echo "$mac  $ip"; done

(With the nmap solution, you could also remove the -n option, and adapt the regex to get the name. If you really enjoy regular expressions).

mivk
  • 3,457
  • 1
  • 34
  • 29
1

A tool that will handle the majority of this is arpwatch. By default (on Debian, at least) is that it writes to /var/lib/arpwatch/arp.dat. This file is flushed and updated each time arpwatch is stopped.

The file contains entries of this form:

52:54:00:aa:bb:cc  192.168.1.2  1452252063  somehostname  eth0

The /etc/ethers file requires only the MAC address and either the IP address or resolvable hostname:

52:54:00:aa:bb:cc  192.168.1.2

It is then quite straightforward to keep /etc/ethers updated and in sync with a small script, run daily from crontab:

#!/bin/bash

# Flush arp.dat
service arpwatch restart

# Save a copy
test -f /etc/ethers || touch /etc/ethers
cp -fp /etc/ethers /etc/ethers.old

# Check to see if anything new has arrived. If so rebuild the file
(
    echo '# This file is updated automatically from /var/lib/arpwatch/arp.dat'
    echo '# Take care when editing'
    echo '#'
    (
        awk '{print $1,$2}' /var/lib/arpwatch/arp.dat
        grep -v '^#' /etc/ethers.old
    ) |
        sort -u
) >/etc/ethers.tmp

# Update ethers with the new file
cmp -s /etc/ethers.tmp /etc/ethers || cat /etc/ethers.tmp >/etc/ethers
rm -f /etc/ethers.tmp

# All done
exit 0
roaima
  • 1,567
  • 13
  • 26
0

arp -a will list the ARP cache table on your system which should show the MAC addresses for IP addresses on your computer's local subnet that you have recently accessed. However for your intended use, this table may not be useful as entries in that table can and will get removed after some period of time. This period of time is OS TCP stack implementation dependent.

Of course it would be possible to have a constantly running script that periodically performs the arp -a command and updates a file with the new information retrieved.

HeatfanJohn
  • 366
  • 5
  • 14
  • I don't mind manually creating / editing the file. The trouble is actually accessing the file and extracting the MAC address. Do you think I would have to write this myself? The only language I really know is PHP! - mind you, I don't mind learning a bit of bash in order to solve a problem. – Fela Maslen Aug 08 '12 at 18:53
0

I've written a little script that retrieves the mac-address and hostname or ip-address from the dhcpd.conf and then construct the wakeup packet (improved version of someone else' perl script). If you want, I can put it on pastebin.com or such.

ott--
  • 1,081
  • 1
  • 11
  • 13