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.