Hack 32 Create a Static ARP Table

figs/moderate.gif figs/hack32.gif

Use static ARP table entries to combat spoofing and other nefarious activities.

As discussed in [Hack #31], a lot of bad things can happen if someone successfully poisons the ARP table of a machine on your network. The previous hack discussed how to monitor for this behavior, but how do we prevent the effects of someone attempting to poison an ARP table?

One way to prevent the ill effects of this behavior is to create static ARP table entries for all of the devices on your local network segment. When this is done, the kernel will ignore all ARP responses for the specific IP address used in the entry and use the specified MAC address instead.

To do this, you can use the arp command, which allows you to directly manipulate the kernel's ARP table entries. To add a single static ARP table entry, run this:

arp -s ipaddr macaddr

If you know that the MAC address that corresponds to is 00:50:BA:85:85:CA, you could add a static ARP entry for it like this:

# arp -s 00:50:ba:85:85:ca

For more than a few entries, this can be a time-consuming process. To be fully effective, you must add an entry for each device on your network on every host that allows you to create static ARP table entries.

Luckily, most versions of the arp command can take a file as input and use it to create static ARP table entries. Under Linux, this is done with the -f command-line switch. Now all you need to do is generate a file containing the MAC and IP address pairings, which you can then copy to all the hosts on your network.

To make this easier, you can use this quick-n-dirty Perl script:



# gen_ethers.pl <from ip> <to ip>


my ($start_1, $start_2, $start_3, $start_4) = split(/\./, $ARGV[0], 4);

my ($end_1, $end_2, $end_3, $end_4) = split(/\./, $ARGV[1], 4); 

my $ARP_CMD="/sbin/arp -n";

for(my $oct_1 = $start_1; $oct_1 <= $end_1 && $oct_1 <= 255; $oct_1++ ){

  for(my $oct_2 = $start_2; $oct_2 <= $end_2 && $oct_2 <= 255; $oct_2++){

    for(my $oct_3 = $start_3; $oct_3 <= $end_3 && $oct_3 <= 255; $oct_3++){

      for(my $oct_4 = $start_4; $oct_4 <= $end_4 && $oct_4 < 255; $oct_4++){

    system("ping -c 1 -W 1 $oct_1.$oct_2.$oct_3.$oct_4 > /dev/null 2>&1");

          my $ether_addr = `$ARP_CMD $oct_1.$oct_2.$oct_3.$oct_4 | egrep 'HWaddress|

(incomplete)' | awk '{print \$3}'`;


    if(length($ether_addr) == 17){







This script will take a range of IP addresses and attempt to ping each one once. In doing this, each active IP address will appear in the machine's ARP table. After an IP address is pinged, the script will then look for that IP address in the ARP table, and print out the MAC/IP address pair in a format suitable for putting into a file to load with the arp command. This script was written with Linux in mind but should work on other Unix-like operating systems as well.

For example, if you wanted to generate a file for all the IP addresses from to and store the results in /etc/ethers, you would run the script like this:

# ./gen_ethers > /etc/ethers

When using arp with the -f switch, it will automatically use the /etc/ethers file to create the static entries. However, you can specify any file you prefer. For example, if you wanted to use /root/arp_entries instead, you would run this:

# arp -f /root/arp_entries

This script isn't perfect, but it can save a lot of time when creating static ARP table entries for the hosts on your network. Once you've generated the file with the MAC/IP pairings, you can copy it to the other hosts and add an arp command to the system startup scripts, to automatically load them at boot time. The main downside to using this method is that all the devices on your network need to be powered on when the script runs; otherwise, they will be missing from the list. In addition, if the machines on your network change frequently, you'll have to regenerate and distribute the file often, which may be more trouble than it's worth. But for servers and devices that never change their IP or MAC address, this method can protect your machines from ARP poisoning attacks.