DHCPV4: add function ValidateOptions()

This add a new function ValidateOptions() in DHCPV4.
Codes for validating the DHCP options are removed and
unified into this new function.

Bug: 25642025
TEST=compile, unittest, and run it.
Change-Id: I92438469e6b1a0b1558a125dda2768db6f1092a1
diff --git a/dhcpv4.cc b/dhcpv4.cc
index cc9e621..dce3191 100644
--- a/dhcpv4.cc
+++ b/dhcpv4.cc
@@ -264,25 +264,9 @@
   }
   LOG(INFO) << "Lease IP: " << IPtoString(your_ip_address);
 
-  uint32_t lease_time = msg.lease_time();
-  if (lease_time == 0) {
-    LOG(ERROR) << "Reject invalid lease time from server";
+  if (!ValidateOptions(msg)) {
     return;
   }
-  LOG(INFO) << "Lease Time: " << lease_time;
-
-  if (msg.subnet_mask() == 0) {
-    LOG(ERROR) << "Reject invalid subnet mask from server";
-    return;
-  }
-  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);
@@ -326,51 +310,14 @@
   }
   LOG(INFO) << "Lease IP: " << IPtoString(your_ip_address);
 
-  uint32_t lease_time = msg.lease_time();
-  if (lease_time == 0 && state_ == State::REQUEST) {
-    LOG(ERROR) << "Reject invalid lease time from server";
+  if (!ValidateOptions(msg)) {
     return;
   }
-  LOG(INFO) << "Lease Time: " << lease_time;
-
-  if (msg.subnet_mask() != subnet_mask_) {
-    LOG(ERROR) << "Reject invalid subnet mask from server";
-    return;
-  }
-  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) {
-    LOG(ERROR) << "Failed to get default gateway address from DHCP Ack";
-    return;
-  }
-  LOG(INFO) << "Routers:";
-  for (uint32_t ip : router) {
-    LOG(INFO) << IPtoString(ip);
-  }
-
-  std::vector<uint32_t> dns_server = msg.dns_server();
-  if (dns_server.size() == 0) {
-    LOG(WARNING) << "Failed to get DNS server address from DHCP Ack";
-    // Shill will use Google DNS server
-    // in case no DNS server is provided by DHCP.
-  } else {
-    LOG(INFO) << "DNS Server:";
-    for (uint32_t ip : dns_server) {
-      LOG(INFO) << IPtoString(ip);
-    }
-  }
 
   // TODO(nywang): Validate the ip address using ARP.
   // TODO(nywang): Validate the gateway address using ARP.
   // Accept the ACK.
+  uint32_t lease_time = msg.lease_time();
   uint32_t renewal_time = lease_time * kRenewalTimePercentage / 100;
   uint32_t rebinding_time = lease_time * kRebindTimePercentage / 100;
   // Override the renewal time or rebinding time if ACK specifies the value.
@@ -613,6 +560,51 @@
   return true;
 }
 
+bool DHCPV4::ValidateOptions(const DHCPMessage& msg) {
+  uint32_t lease_time = msg.lease_time();
+  if (lease_time == 0) {
+    LOG(ERROR) << "Reject invalid lease time";
+    return false;
+  }
+  LOG(INFO) << "Lease Time: " << lease_time;
+
+  if (msg.subnet_mask() == 0) {
+    LOG(ERROR) << "Reject invalid subnet mask";
+    return false;
+  }
+  LOG(INFO) << "Subnet Mask: " << IPtoString(msg.subnet_mask());
+
+  if (msg.interface_mtu() == 0) {
+    LOG(WARNING) << "Failed to get a valid Interface MTU";
+    // 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) {
+    LOG(ERROR) << "Failed to get default gateway address";
+    return false;
+  }
+  LOG(INFO) << "Routers:";
+  for (uint32_t ip : router) {
+    LOG(INFO) << IPtoString(ip);
+  }
+
+  std::vector<uint32_t> dns_server = msg.dns_server();
+  if (dns_server.size() == 0) {
+    LOG(WARNING) << "Failed to get DNS server address";
+    // Shill will use Google DNS server
+    // in case no DNS server is provided by DHCP.
+  } else {
+    LOG(INFO) << "DNS Server:";
+    for (uint32_t ip : dns_server) {
+      LOG(INFO) << IPtoString(ip);
+    }
+  }
+  return true;
+}
+
 int DHCPV4::ValidatePacketHeader(const unsigned char* buffer, size_t len) {
   const struct iphdr* ip =
       reinterpret_cast<const struct iphdr*>(buffer);
diff --git a/dhcpv4.h b/dhcpv4.h
index 5d45a92..78903d7 100644
--- a/dhcpv4.h
+++ b/dhcpv4.h
@@ -62,6 +62,7 @@
   // Validate the IP and UDP header and return the total headers length.
   // Return -1 if any header is invalid.
   int ValidatePacketHeader(const unsigned char* buffer, size_t len);
+  bool ValidateOptions(const DHCPMessage& msg);
   void ResetStateVariables();
 
   const std::string IPtoString(uint32_t ip);