dhcp client: support broadcast address option
am: cf157b7

* commit 'cf157b7512d880b5da8b54443cbbfc13474b795a':
  dhcp client: support broadcast address option

Change-Id: I8457343c76cb4745e739bb735ea6eda33db2a9a6
diff --git a/dhcp_message.cc b/dhcp_message.cc
index 75a3935..3041363 100644
--- a/dhcp_message.cc
+++ b/dhcp_message.cc
@@ -68,12 +68,16 @@
 
 DHCPMessage::DHCPMessage()
     : subnet_mask_(0),
+      interface_mtu_(0),
+      broadcast_address_(0),
       requested_ip_address_(0),
       lease_time_(0),
       message_type_(0),
       server_identifier_(0),
       renewal_time_(0),
       rebinding_time_(0) {
+  options_map_.insert(std::make_pair(kDHCPOptionBroadcastAddr,
+      ParserContext(new UInt32Parser(), &broadcast_address_)));
   options_map_.insert(std::make_pair(kDHCPOptionMessageType,
       ParserContext(new UInt8Parser(), &message_type_)));
   options_map_.insert(std::make_pair(kDHCPOptionLeaseTime,
diff --git a/dhcp_message.h b/dhcp_message.h
index e86b4b3..6b46f33 100644
--- a/dhcp_message.h
+++ b/dhcp_message.h
@@ -81,6 +81,7 @@
   void SetVendorSpecificInfo(const shill::ByteString& vendor_specific_info);
 
   // DHCP option and field getters
+  uint32_t broadcast_address() const { return broadcast_address_; }
   const shill::ByteString& client_hardware_address() const {
     return client_hardware_address_;
   }
@@ -158,6 +159,8 @@
   std::string domain_name_;
   // Option 26: Interface MTU.
   uint16_t interface_mtu_;
+  // Option 28: Broadcast Address.
+  uint32_t broadcast_address_;
   // 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 0ed5bf9..cc843de 100644
--- a/dhcp_options.h
+++ b/dhcp_options.h
@@ -25,6 +25,7 @@
 const uint8_t kDHCPOptionDNSServer = 6;
 const uint8_t kDHCPOptionDomainName = 15;
 const uint8_t kDHCPOptionInterfaceMTU = 26;
+const uint8_t kDHCPOptionBroadcastAddr = 28;
 const uint8_t kDHCPOptionVendorSpecificInformation = 43;
 const uint8_t kDHCPOptionRequestedIPAddr = 50;
 const uint8_t kDHCPOptionLeaseTime = 51;
diff --git a/dhcpv4.cc b/dhcpv4.cc
index c5a3d3a..90d73a5 100644
--- a/dhcpv4.cc
+++ b/dhcpv4.cc
@@ -65,6 +65,7 @@
 const uint8_t kDefaultParameterRequestList[] = {
     kDHCPOptionSubnetMask,
     kDHCPOptionInterfaceMTU,
+    kDHCPOptionBroadcastAddr,
     kDHCPOptionRouter,
     kDHCPOptionDNSServer,
     kDHCPOptionDomainName,
@@ -101,6 +102,8 @@
 // In this way shill can include this header and parse
 // the messages.
 
+const char kConfigurationKeyBroadcastAddress[] =
+    "BroadcastAddress";
 const char kConfigurationKeyDNS[] = "DomainNameServers";
 const char kConfigurationKeyDomainName[] = "DomainName";
 const char kConfigurationKeyIPAddress[] = "IPAddress";
@@ -429,6 +432,7 @@
   // Set the option parameters.
   subnet_mask_ = msg.subnet_mask();
   interface_mtu_ = msg.interface_mtu();
+  broadcast_address = msg.broadcast_address();
   router_ = msg.router();
   dns_server_ = msg.dns_server();
   vendor_specific_info_ = msg.vendor_specific_info();
@@ -744,16 +748,23 @@
     // Shill will use a default MTU
     // in case no MTU is provided by DHCP.
   }
-  LOG(INFO) << "Interface MTU: " << msg.interface_mtu();
+  DLOG(INFO) << "Interface MTU: " << msg.interface_mtu();
+
+  if (msg.broadcast_address() == 0) {
+    LOG(WARNING) << "Failed to get a valid Broadcast Address";
+    // Shill will use a default broadcast address
+    // in case no broadcast address is provided by DHCP.
+  }
+  DLOG(INFO) << "Broadcast Address: " << IPtoString(msg.broadcast_address());
 
   std::vector<uint32_t> router = msg.router();
   if (router.size() == 0) {
     LOG(ERROR) << "Failed to get default gateway address";
     return false;
   }
-  LOG(INFO) << "Routers:";
+  DLOG(INFO) << "Routers:";
   for (uint32_t ip : router) {
-    LOG(INFO) << IPtoString(ip);
+    DLOG(INFO) << IPtoString(ip);
   }
 
   std::vector<uint32_t> dns_server = msg.dns_server();
@@ -762,9 +773,9 @@
     // Shill will use Google DNS server
     // in case no DNS server is provided by DHCP.
   } else {
-    LOG(INFO) << "DNS Server:";
+    DLOG(INFO) << "DNS Server:";
     for (uint32_t ip : dns_server) {
-      LOG(INFO) << IPtoString(ip);
+      DLOG(INFO) << IPtoString(ip);
     }
   }
   return true;
@@ -830,6 +841,7 @@
   if (reason == kReasonBound) {
     configs.emplace(kConfigurationKeyIPAddress, client_ip_);
     configs.emplace(kConfigurationKeyMTU, interface_mtu_);
+    configs.emplace(kConfigurationKeyBroadcastAddress, broadcast_address_);
     configs.emplace(kConfigurationKeyRouters, router_);
     configs.emplace(kConfigurationKeyDNS, dns_server_);
     configs.emplace(kConfigurationKeyVendorEncapsulatedOptions,
diff --git a/dhcpv4.h b/dhcpv4.h
index 0d29467..411cf66 100644
--- a/dhcpv4.h
+++ b/dhcpv4.h
@@ -131,6 +131,8 @@
   uint32_t server_ip_;
   // Interface mtu.
   uint16_t interface_mtu_;
+  // Broadcast address.
+  uint32_t broadcast_address_;
   // Aka Default Gateway.
   std::vector<uint32_t> router_;
   // Domain Name Servers.