shill: LinkMonitor: Add ArpClient code

Add ArpClient class and start hooking it up to LinkMonitor.

BUG=chromium-os:32600
TEST=Unit tests.  Some real-world testing using the test harness
to transmit and receive ARP on a real network.

Change-Id: Ic05d8d7eb921878e3776f35b4be285554ef86456
Reviewed-on: https://gerrit.chromium.org/gerrit/28148
Commit-Ready: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/arp_packet_unittest.cc b/arp_packet_unittest.cc
index 4cdaa76..952bbd4 100644
--- a/arp_packet_unittest.cc
+++ b/arp_packet_unittest.cc
@@ -31,6 +31,8 @@
 const uint8 kMACAddress1[] = { 0x88, 0x87, 0x86, 0x85, 0x84, 0x83 };
 const uint8 kMACBroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 const uint8 kInsertedByte[] = { 0x00 };
+const size_t kArpPaddingSizeV4 = 18;
+const size_t kArpPaddingSizeV6 = 0;
 }  // namespace {}
 
 class ArpPacketTest : public Test {
@@ -173,6 +175,10 @@
   EXPECT_TRUE(ipv4_address1_.Equals(packet_.remote_ip_address()));
   EXPECT_TRUE(mac_address0_.Equals(packet_.local_mac_address()));
   EXPECT_TRUE(mac_address1_.Equals(packet_.remote_mac_address()));
+
+  // Parse should succeed with arbitrary trailing padding.
+  arp_bytes.Append(ByteString(1000));
+  EXPECT_TRUE(packet_.ParseReply(arp_bytes));
 }
 
 TEST_F(ArpPacketTest, ParseReplyIPv6) {
@@ -245,6 +251,7 @@
   expected_bytes.Append(ipv4_address0_.address());
   expected_bytes.Append(mac_address1_);
   expected_bytes.Append(ipv4_address1_.address());
+  expected_bytes.Append(ByteString(kArpPaddingSizeV4));
   EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
 }
 
@@ -261,6 +268,7 @@
   expected_bytes.Append(ipv6_address0_.address());
   expected_bytes.Append(mac_address0_);
   expected_bytes.Append(ipv6_address1_.address());
+  expected_bytes.Append(ByteString(kArpPaddingSizeV6));
   EXPECT_TRUE(expected_bytes.Equals(arp_bytes));
 }