dhcp client: support DHCP option 'interface mtu'

This allows the server to specify the MTU to use on this
interface.

Bug: 25642025
TEST=compile and unittes

Change-Id: I8850a91ff403a336c533d15b54902ddd0ed10b76
diff --git a/dhcp_message.cc b/dhcp_message.cc
index 84a7ea8..75a3935 100644
--- a/dhcp_message.cc
+++ b/dhcp_message.cc
@@ -96,6 +96,8 @@
       ParserContext(new StringParser(), &domain_name_)));
   options_map_.insert(std::make_pair(kDHCPOptionVendorSpecificInformation,
       ParserContext(new ByteArrayParser(), &vendor_specific_info_)));
+  options_map_.insert(std::make_pair(kDHCPOptionInterfaceMTU,
+      ParserContext(new UInt16Parser(), &interface_mtu_)));
 }
 
 DHCPMessage::~DHCPMessage() {}
diff --git a/dhcp_message.h b/dhcp_message.h
index 60d119c..e86b4b3 100644
--- a/dhcp_message.h
+++ b/dhcp_message.h
@@ -91,6 +91,7 @@
   const std::vector<uint32_t>& dns_server() const { return dns_server_; }
   const std::string& domain_name() const { return domain_name_; }
   const std::string& error_message() const { return error_message_; }
+  uint16_t interface_mtu() const { return interface_mtu_; }
   uint32_t lease_time() const { return lease_time_; }
   uint8_t message_type() const { return message_type_; }
   uint32_t rebinding_time() const { return rebinding_time_; }
@@ -155,6 +156,8 @@
   std::vector<uint32_t> dns_server_;
   // Option 15: Domain Name.
   std::string domain_name_;
+  // Option 26: Interface MTU.
+  uint16_t interface_mtu_;
   // Option 43: Vendor Specific Information.
   shill::ByteString vendor_specific_info_;
   // Option 50: Requested IP Address.
diff --git a/dhcp_options.h b/dhcp_options.h
index c215253..0ed5bf9 100644
--- a/dhcp_options.h
+++ b/dhcp_options.h
@@ -24,6 +24,7 @@
 const uint8_t kDHCPOptionRouter = 3;
 const uint8_t kDHCPOptionDNSServer = 6;
 const uint8_t kDHCPOptionDomainName = 15;
+const uint8_t kDHCPOptionInterfaceMTU = 26;
 const uint8_t kDHCPOptionVendorSpecificInformation = 43;
 const uint8_t kDHCPOptionRequestedIPAddr = 50;
 const uint8_t kDHCPOptionLeaseTime = 51;
diff --git a/dhcpv4.cc b/dhcpv4.cc
index 88ebd6c..cc9e621 100644
--- a/dhcpv4.cc
+++ b/dhcpv4.cc
@@ -57,6 +57,7 @@
 // DHCP parameters we request from server.
 const uint8_t kDefaultParameterRequestList[] = {
     kDHCPOptionSubnetMask,
+    kDHCPOptionInterfaceMTU,
     kDHCPOptionRouter,
     kDHCPOptionDNSServer,
     kDHCPOptionDomainName,
@@ -274,7 +275,14 @@
     LOG(ERROR) << "Reject invalid subnet mask from server";
     return;
   }
-  LOG(INFO) << "Subnet mask: " << IPtoString(msg.subnet_mask());
+  LOG(INFO) << "Subnet Mask: " << IPtoString(msg.subnet_mask());
+
+  if (msg.interface_mtu() == 0) {
+    LOG(WARNING) << "Failed to get a valid Interface MTU from server";
+    // Shill will use a default MTU
+    // in case no MTU is provided by DHCP.
+  }
+  LOG(INFO) << "Interface MTU: " << msg.interface_mtu();
 
   // Accept this offer.
   LOG(INFO) << "Accept offer with ip: " << IPtoString(your_ip_address);
@@ -329,7 +337,14 @@
     LOG(ERROR) << "Reject invalid subnet mask from server";
     return;
   }
-  LOG(INFO) << "Subnet mask: " << IPtoString(msg.subnet_mask());
+  LOG(INFO) << "Subnet Mask: " << IPtoString(msg.subnet_mask());
+
+  if (msg.interface_mtu() == 0) {
+    LOG(WARNING) << "Failed to get a valid Interface MTU from server";
+    // Shill will use a default MTU
+    // in case no MTU is provided by DHCP.
+  }
+  LOG(INFO) << "Interface MTU: " << msg.interface_mtu();
 
   std::vector<uint32_t> router = msg.router();
   if (router.size() == 0) {