Earlier we posted about new issues we’ve discovered with ARP implementations in the areas of security and robustness. In CDRouter 10.5 we added new tests to handle these discoveries. Here’s how they work:
Testing These Issues with CDRouter
The first three tests in the new ARP module, arp_1, arp_2, and arp_3, are basic tests that are designed to verify that the Device Under Test (DUT) responds to different types of ARP requests from clients on the LAN. Specifically, these tests verify the following:
arp_1: Verify DUT responds to broadcast ARP request on LAN interface.
A broadcast ARP request:
arp_2: Verify DUT responds to unicast ARP request on LAN interface.
A unicast ARP request:
arp_3: Verify DUT responds to ARP Probes on the LAN interface.
An ARP probe:
The arp_3 test case verifies that the DUT responds to “ARP Probes”. An ARP Probe is a special type of unsolicited ARP request that is used in address conflict detection (ACD) as defined in RFC 5227. Section 1.1 of RFC 5227 formally defines an ARP Probe as follows:
In this document, the term ‘ARP Probe’ is used to refer to an ARP Request packet, broadcast on the local link, with an all-zero ‘sender IP address’. The ‘sender hardware address’ MUST contain the hardware address of the interface sending the packet. The ‘sender IP address’ field MUST be set to all zeroes, to avoid polluting ARP caches in other hosts on the same link in the case where the address turns out to be already in use by another host. The ‘target hardware address’ field is ignored and SHOULD be set to all zeroes. The ‘target IP address’ field MUST be set to the address being probed. An ARP Probe conveys both a question (“Is anyone using this address?”) and an implied statement (“This is the address I hope to use.”).
RFC 5227 Section 1.1 also defines “ARP Announcements”, which are another type of unsolicited ARP request used in ACD:
In this document, the term ‘ARP Announcement’ is used to refer to an ARP Request packet, broadcast on the local link, identical to the ARP Probe described above, except that both the sender and target IP address fields contain the IP address being announced. It conveys a stronger statement than an ARP Probe, namely, “This is the address I am now using.”
An ARP Announcement is also known as a Gratuitous ARP Request. The general term “Gratuitous ARP”, or GARP, can be traced back to W. Richard Stevens(Chapter 4 “ARP”, TCP/IP Illustrated, Volume 1; W. Richard Stevens), who defines it explicitly as an ARP Request packet. However, Section 4.6 of RFC 2002 expands on this and states that a Gratuitous ARP MAY be an ARP Request or Reply:
A Gratuitous ARP  is an ARP packet sent by a node in order to spontaneously cause other nodes to update an entry in their ARP cache. A gratuitous ARP MAY use either an ARP Request or an ARP Reply packet. In either case, the ARP Sender Protocol Address and ARP Target Protocol Address are both set to the IP address of the cache entry to be updated, and the ARP Sender Hardware Address is set to the link-layer address to which this cache entry should be updated. When using an ARP Reply packet, the Target Hardware Address is also set to the link-layer address to which this cache entry should be updated (this field is not used in an ARP Request packet).
Section 4 of RFC 5227 provides some historical information and clarifies that an ARP Announcement is indeed the same as a Gratuitous ARP Request as defined by Stevens.
ARP Cache Tests
The next group of tests in the ARP module, arp_10, arp_11, arp_12, and arp_13, all verify that the DUT updates its ARP cache for existing entries when certain types of unsolicited ARP packets are received:
arp_10: Verify DUT updates ARP cache when ARP request is received.
An ARP request:
arp_11: Verify DUT updates ARP cache when ARP reply is received.
An ARP reply:
arp_12: Verify DUT updates ARP cache when a gratuitous ARP request is received.
A gratuitous ARP request:
arp_13: Verify DUT updates ARP cache when a gratuitous ARP reply is received.
A gratuitous ARP reply:
The underlying requirement that is used as the basis for these four tests is defined in the “Packet Reception” section of RFC 826. This section specifically states that the cache (aka translation table) should be updated when processing an ARP packet:
If the pair
is already in my translation table, update the sender hardware address field of the entry with the new information in the packet and set Merge_flag to true.
These four ARP cache tests are all very similar. At the start of each test a new host is created on the LAN,
host2, which obtains its IP address via DHCP from the DUT. After performing a quick ping test, which will ensure that host2 has an entry within the DUT’s ARP cache, the address is released. A second host is then created on the LAN,
host3, with a unique MAC address. Host3 is manually assigned the address host2 received earlier in the test.
This creates an address conflict allowing the DUT’s ARP cache behavior to be examined by sending various types of ARP packets from host3 to the DUT (each of the four tests above focuses on the ARP cache behavior with respect to a specific type of ARP packet). Upon reception of these ARP packets the DUT should in most cases automatically update the existing entry in its ARP cache with host3’s MAC address.
Pinging the DUT from host3 will reveal the DUT’s ARP cache behavior. One of three possible outcomes is expected:
- If the DUT automatically updated its ARP cache with host3’s MAC address, as expected, it will send ping responses to host3 without having to ARP for host3’s IP
- If the DUT did not automatically update its ARP cache with host3’s MAC address it may ARP for host3’s IP before sending ping responses to host3
- If the DUT did not automatically update its ARP cache with host3’s MAC address it may send ping responses to host2’s MAC address
Outcome 3 will cause all four test cases to fail. Outcome 1 will lead to tests arp_10 and arp_11 passing. Tests arp_13 and arp_14 are configurable based on the DUT’s expected behavior with respect to Gratuitous ARPs. For security reasons, some implementations are explicitly configured to ignore Gratuitous ARP packets (both requests and replies).
arpSupportsGratuitous can be used to specify the DUT’s Gratuitous ARP behavior. If set to “yes”, the DUT is expected to update its ARP cache automatically when Gratuitous ARPs are received - tests arp_12 and arp_13 will only pass if response 1 is received. If
arpSupportsGratuitous is set to “no”, the DUT should ignore Gratuitous ARPs and not update its ARP cache when they are received - tests arp_12 and arp_13 will only pass if response 2 is received.
Two negative tests are also included in the ARP module, arp_20 and arp_50.
arp_20: Verify DUT does not respond to bad ARP Requests.
arp_50: Verify DUT ignores spoofed ARP reply for WAN gateway.
The arp_20 test case is designed to verify that the DUT ignores ARP requests for a set of target IP addresses that may be configured on the DUT. Specifically, broadcast ARP requests are sent for the following target IP addresses:
127.0.0.01 255.255.255.255 0.0.0.0 126.96.36.199
The DUT should not respond to any of these ARP requests.
The arp_50 test case verifies that the DUT ignores spoofed ARP replies for the DUT’s WAN default gateway on the LAN. This test was written to expose a potential DoS vulnerability that was uncovered during development and testing. Some devices will respond to ARP requests for the WAN default gateway on the LAN. This allows a LAN client to alter the default route of the DUT and create a DoS situation.
For optimal security the DUT should only process ARP packets that contain information relevant to the receiving interface. ARP packets that contain target IP addresses that may be configured on an interface other than the receiving interface should be ignored.
ARP Leak Tests
The arp_30 and arp_31 tests are designed to verify that the DUT does not “leak” ARP information across interface boundaries.
These are a type of CDRouter test that analyze data generated from previous tests and produce a failure if certain packets are received from the DUT during prior tests. The arp_30 and arp_31 test cases are specifically analyzing the ARP history of all LAN clients and WAN hosts, respectively, that have been created up to the point where the tests were executed during a particular test run.
To ensure that the largest possible data set is analyzed, these tests should be executed at the end of a test run or at multiple points during a test run.
arp_30: Verify DUT does not leak WAN side addresses on LAN via ARP.
arp_31: Verify DUT does not leak LAN side addresses on WAN via ARP.
The DUT should only send ARP requests for its default gateway on the WAN. Sending these requests out on the LAN leaks the default gateway address making it possible for malicious clients to spoof the default gateway and influence the DUT’s routing table. This can lead to a DoS situation for other LAN clients. The arp_30 test case can be used to verify that the DUT is not leaking WAN side ARP information on the LAN. Likewise, the arp_31 test case can be used to verify that the DUT is not leaking LAN side information on the WAN.
ARP Mode Test
There are many options within the Linux kernel that control the behavior of ARP. The default values are often not optimal for a typical gateway device and should be modified to limit possible security vulnerabilities.
The arp_40 test case is designed to examine and classify the DUT’s ARP behavior.
arp_40: Verify DUT ARP mode behavior - open, restricted, strict.
The DUT’s ARP implementation can be examined by analyzing its response to two different ARP requests. First, an ARP request for the DUT’s WAN IP is sent on the LAN. Second, an ARP request for the DUT’s LAN IP is sent on the LAN from a client that is not within the DUT’s LAN subnet.
The DUT’s response to these two ARP requests allows CDRouter to classify its ARP implementation as one of three different types:
- open: the DUT will reply for any local target IP address, configured on any interface
- restricted: the DUT will reply only if the target IP address is a local address configured on the incoming interface
- strict: the DUT will reply only if the target IP address is a local address configured on the incoming interface and if the sender’s IP address is within the same subnet.
arpMode testvar can be used to specify the DUT’s expected type of ARP implementation. The default and recommended value for this testvar is
ARP Stress Tests
The final set of tests included in the ARP module are arp_60 and arp_61. These are ARP stress tests that are designed to verify that the DUT is able to handle a large number of incoming ARP requests and replies, respectively, on the LAN.
If the test interface is Ethernet, 500 ARP requests or replies will be sent from new LAN clients with unique source MAC addresses. This limit is reduced to 20 for wireless test interfaces.
arp_60: Verify DUT handles a large number of ARP requests with unique MAC addresses.
arp_61: Verify DUT handles a large number of ARP replies with unique MAC addresses.
In some devices, these tests have induced unexpected behavior, such as ARP cache corruption.
Testing Exercises with CDRouter
Like all of our test modules, we recommend that you run them multiple times. Ideally, your testing should be time based and not test count based. How much time can you dedicate to ARP testing? When was the last time you stressed your ARP implementation?
Try out some of the following CDRouter test exercises:
Run the arp.tcl module along with nat.tcl and perf.tcl once and make sure all tests pass. Turn control mode on for your perf.tcl to allow you to debug any performance related ARP issues. Run these tests in a continuous loop for 24+ hours to see if any new failures are revealed.
Run the the arp.tcl module along with the DHCP server dhcp-s.tcl module. Run the tests once to make sure everything works from a clean reboot. Create a test run that uses both wired and wireless LAN interfaces. Repeat these tests in a loop for 24+ hours.
The arp.tcl module also introduces a new type of CDRouter test that analyzes data generated from previous tests (arp_30 and arp_31). In these cases the data being analyzed is the ARP history of all LAN or WAN clients, respectively, that have been created up to the point where these tests were executed during a particular test run. To ensure that the largest possible data set is analyzed, these test should be executed at the end of a test run or at multiple points during a test run.
Good luck with your testing!