MacOS – Add Static ARP Entry at Boot

bootlaunchdmacosterminal

I'm new to Mac OS X.
On Linux I'd:

append to /etc/rc.local
arp -i eth0 -s 192.168.1.1 00:00:00:00:00:00

I've figured out how to do it in Terminal:

sudo arp -s 192.168.1.1 00:00:00:00:00:00

But I'd like this to happen automatically preferably at boot.
Also do I need to specify an interface when using arp?

I read some other SE answers that mentioned launchd, but I have no idea what that is.

Best Answer

I struggled a lot with Matthieu's solution since it caused two problems on my Mac OS X 10.9.2:

  1. Jobs in the LaunchAgents folder are executed using the current user. However arp needs to be executed using root.
  2. The arp-command is executed too early, when the network is not up. But the network is needed by the arp-command.

The first problem can be solved by storing the .plist file in LaunchDaemons instead of LaunchAgents. This will ensure that the command is executed as root.

The second problem is a bit tricky. Since launchd does not handle dependencies, we have to write our own shell script which first waits until the network is up an then execute the arp command. (See here)

So here is my solution:
First create/open the plist file using a text-editor:

sudo nano /Library/LaunchDaemons/local.arpentries.plist

Then paste the following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>local.arpentries</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/arpentries</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
</dict>
</plist>

Set owner etc.:

sudo chown root:wheel /Library/LaunchDaemons/local.arpentries.plist
sudo chmod 0644 /Library/LaunchDaemons/local.arpentries.plist

Now create/open the shell script using a text editor

sudo nano /usr/local/bin/arpentries

Paste the following:

#!/bin/bash

# max number of retries
retries=10

# include Startup commons
. /etc/rc.common

# wait for network to become available
CheckForNetwork

while [ "$NETWORKUP" != "-YES-" ]
do
        retries=$((retries - 1))
        if [ $retries -le 0 ] ; then
                exit 1
        fi
        sleep 2
        NETWORKUP=
        CheckForNetwork
done

# set the static arp entries
arp -s 192.168.1.111 xx:xx:xx:xx:xx:xx

exit 0

And the rights:

sudo chmod 0744 /usr/local/bin/arpentries