Display, Add, Flush arpcache In Linux With ‘arp’

The arp table or arp cache keeps track of all devices on your network that your computer is capable of communicating with. It stores the Layer 2 data ( MAC addresses ) as well as the interface in which the device is connected through (i.e. which interface the traffic came in on ). This table can be viewed, modified, flushed using the arp command in Linux. To view this table you can be running as a normal user, but to make modifications to this table you must be running as a super user aka root because it interfaces with the kernel. The options the arp command provides are:

$ arp --help
Usage:
  arp [-vn]  [<HW>] [-i <if>] [-a] [<hostname>]             <-Display ARP cache
  arp [-v]          [-i <if>] -d  <host> [pub]               <-Delete ARP entry
  arp [-vnD] [<HW>] [-i <if>] -f  [<filename>]            <-Add entry from file
  arp [-v]   [<HW>] [-i <if>] -s  <host> <hwaddr> [temp]            <-Add entry
  arp [-v]   [<HW>] [-i <if>] -Ds <host> <if> [netmask <nm>] pub          <-''-
 
        -a                       display (all) hosts in alternative (BSD) style
        -s, --set                set a new ARP entry
        -d, --delete             delete a specified entry
        -v, --verbose            be verbose
        -n, --numeric            do not resolve names
        -i, --device             specify network interface (e.g. eth0)
        -D, --use-device         read <hwaddr> from given device
        -A, -p, --protocol       specify protocol family
        -f, --file               read new entries from file or from /etc/ethers

Lets look at viewing the current arp cache entries.

View Arp Cache Entries

There are at least two ways to view the current arp cache entries. Using the arp utility we can view the current arp entries. I prefer to use the -n option to view the results immediately. The -n will stop the name resolution and just simply display the IP address, otherwise the system tries to identify the actual name (if specified by dns) of the IP.

$ arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.16.35             ether   00:0e:22:8b:2e:60   C                     eth0
192.168.16.174            ether   00:bb:23:11:13:33   C                     eth0
192.168.16.199            ether   00:1b:24:aa:22:fc   C                     eth0
192.168.16.32             ether   00:30:48:59:6b:48   C                     eth0
192.168.16.1              ether   00:11:39:af:aa:4a   C                     eth0
192.168.16.160            ether   00:26:b9:2c:7a:53   C                     eth0
192.168.16.165            ether   00:1a:a4:1f:b6:7b   C                     eth0

Chatty network. These are all the machines my computer has communicated with. This table is used when sending traffic out, it can identify which interface to send traffic out on. With multiple interfaces this makes more sense.

We can also view the arp entries using /proc/net/arp, doing a cat on that file will produce the same output as running through the arp command.

Perhaps you want to add a static arp entry.

Add Static Arp Entry

To add an arp entry we simply take advantage of the options that the arp command provides. Lets add an arbitrary entry.

# arp -i eth0 -s 10.11.12.13 de:ad:be:ef:fe:ed

Note, I am running as root to add this entry. Lets have a look at the table now:

# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.16.35             ether   00:0e:22:8b:2e:60   C                     eth0
192.168.16.174            ether   00:bb:23:11:13:33   C                     eth0
10.11.12.13              ether   de:ad:be:ef:fe:ed   CM                    eth0
192.168.16.199            ether   00:1b:24:aa:22:fc   C                     eth0
192.168.16.32             ether   00:30:48:59:6b:48   C                     eth0
192.168.16.1              ether   00:11:39:af:aa:4a   C                     eth0
192.168.16.160            ether   00:26:b9:2c:7a:53   C                     eth0
192.168.16.165            ether   00:1a:a4:1f:b6:7b   C                     eth0

Notice line 5 is where my entry landed. Also notice the additional M under the Flags column. Voila, you now have an entry for 10.11.12.13 using interface eth0. If you wanted a different interface simply replace the value from my above example.

Perhaps over time you become sick of the new entry, it doesn’t pay rent or keep the place clean so its time to get rid of it!

Remove Entry From Arp Cache

To remove an entry we can refer to the initial help output I pasted above.

  arp [-v]          [-i <if>] -d  <host> [pub]               <-Delete ARP entry

So in our case, we will be removing 10.11.12.13 from the arp cache.

# arp -i eth0 -d 10.11.12.13

That entered without a hitch, lets verify that it is now gone:

# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.16.35             ether   00:0e:22:8b:2e:60   C                     eth0
192.168.16.174            ether   00:bb:23:11:13:33   C                     eth0
192.168.16.199            ether   00:1b:24:aa:22:fc   C                     eth0
192.168.16.32             ether   00:30:48:59:6b:48   C                     eth0
192.168.16.1              ether   00:11:39:af:aa:4a   C                     eth0
192.168.16.160            ether   00:26:b9:2c:7a:53   C                     eth0
192.168.16.165            ether   00:1a:a4:1f:b6:7b   C                     eth0

Excellent! Unfortunately, the Linux arp command has no global flush option. But wait! You saw how basic the line for a delete is. Lets just make a simple shell script to remove multiple entries.

Flush Arp Cache With This Shell Script

To flush our arp cache we just need to construct a basic shell script to do so. Of course we will have to run as root when executing the command! Here is a simple script to flush the arp cache. Depending on how large your arp cache is, is related to how fast/slow it takes to remove all entries. Also remember that once your system receives a packet from any other host computer, the entry will be added back into the arp cache. The interface entry is optional, arp requires only the IP address during removal.

#!/bin/sh
 
for i in `awk -F ' ' '{ if ( $1 ~ /[0-9{1,3}].[0-9{1,3}].[0-9{1,3}].[0-9{1,3}]/ ) print $1 }' /proc/net/arp` ; 
do 
    arp -d $i 
done

This example takes advantage of the /proc/net/arp file to grab all IP addresses. We could also call arp -n and parse its output for the IP addresses. It just makes more sense to read from a file rather than spawning a shell command to execute arp.