dnsmasq: patch to write dhcp options into the lease file

BUG=b:26814267
TEST=verified restart, reboot, and options can be read.

Change-Id: I361937da8c6292f3a6d1f641b857e905793a6c84
Reviewed-on: https://chromium-review.googlesource.com/324190
Commit-Ready: Christopher Book <cbook@chromium.org>
Tested-by: Christopher Book <cbook@chromium.org>
Reviewed-by: Zeping Qiu <zqiu@chromium.org>
diff --git a/net-dns/dnsmasq/dnsmasq-2.72-r3.ebuild b/net-dns/dnsmasq/dnsmasq-2.72-r4.ebuild
similarity index 95%
rename from net-dns/dnsmasq/dnsmasq-2.72-r3.ebuild
rename to net-dns/dnsmasq/dnsmasq-2.72-r4.ebuild
index 5322be2..ce4a1f3 100644
--- a/net-dns/dnsmasq/dnsmasq-2.72-r3.ebuild
+++ b/net-dns/dnsmasq/dnsmasq-2.72-r4.ebuild
@@ -13,7 +13,7 @@
 LICENSE="|| ( GPL-2 GPL-3 )"
 SLOT="0"
 KEYWORDS="*"
-IUSE="auth-dns conntrack dbus +dhcp dhcp-tools dnssec idn ipv6 lua nls script selinux static tftp"
+IUSE="auth-dns conntrack dbus +dhcp dhcp-options dhcp-tools dnssec idn ipv6 lua nls script selinux static tftp"
 DM_LINGUAS="de es fi fr id it no pl pt_BR ro"
 for dm_lingua in ${DM_LINGUAS}; do
 	IUSE+=" linguas_${dm_lingua}"
@@ -100,6 +100,9 @@
 
 	epatch "${FILESDIR}"/${P}-Fix-crash-on-receipt-of-certain-malformed-DNS-requests.patch
 	epatch "${FILESDIR}"/${P}-Fix-crash-caused-by-looking-up-servers.bind-when-many-servers-defined.patch
+	if use dhcp-options; then
+		epatch "${FILESDIR}"/${P}-Write-DHCP-request-options-to-lease-file.patch
+	fi
 }
 
 src_configure() {
diff --git a/net-dns/dnsmasq/files/dnsmasq-2.72-Write-DHCP-request-options-to-lease-file.patch b/net-dns/dnsmasq/files/dnsmasq-2.72-Write-DHCP-request-options-to-lease-file.patch
new file mode 100644
index 0000000..5540bff
--- /dev/null
+++ b/net-dns/dnsmasq/files/dnsmasq-2.72-Write-DHCP-request-options-to-lease-file.patch
@@ -0,0 +1,82 @@
+diff --git a/src/dnsmasq.h b/src/dnsmasq.h
+index e74b15a..fbf41f6 100644
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -660,6 +660,7 @@ struct dhcp_lease {
+   } *slaac_address;
+   int vendorclass_count;
+ #endif
++  u8 req_options[256];   /* cover all possible options (0-254 + OPTION_END) */
+   struct dhcp_lease *next;
+ };
+ 
+diff --git a/src/lease.c b/src/lease.c
+index 5d56b1b..a63851e 100644
+--- a/src/lease.c
++++ b/src/lease.c
+@@ -81,7 +81,7 @@ void lease_init(time_t now)
+ 
+ 	ei = atol(daemon->dhcp_buff3);
+ 	
+-	if (fscanf(leasestream, " %64s %255s %764s",
++	if (fscanf(leasestream, " %64s %255s %764s %*s",
+ 		   daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
+ 	  break;
+ 	
+@@ -254,10 +254,25 @@ void lease_update_file(time_t now)
+ 	    {
+ 	      for (i = 0; i < lease->clid_len - 1; i++)
+ 		ourprintf(&err, "%.2x:", lease->clid[i]);
+-	      ourprintf(&err, "%.2x\n", lease->clid[i]);
++	      ourprintf(&err, "%.2x ", lease->clid[i]);
+ 	    }
+ 	  else
+-	    ourprintf(&err, "*\n");	  
++	    ourprintf(&err, "* ");
++
++	  {
++	    unsigned char *p;
++	    if (lease->req_options[0] == OPTION_END)
++	      ourprintf(&err, "*");
++	    else
++	    {
++	      for (p = lease->req_options; *p != OPTION_END; p++)
++	      {
++		if (p != lease->req_options) ourprintf(&err, ",");
++		ourprintf(&err, "%u", *p);
++	      }
++	    }
++	    ourprintf(&err, "\n");
++	  }
+ 	}
+       
+ #ifdef HAVE_DHCP6  
+@@ -729,6 +744,7 @@ static struct dhcp_lease *lease_allocate(void)
+   lease->length = 0xffffffff; /* illegal value */
+ #endif
+   lease->hwaddr_len = 256; /* illegal value */
++  lease->req_options[0] = OPTION_END;
+   lease->next = leases;
+   leases = lease;
+   
+diff --git a/src/rfc2131.c b/src/rfc2131.c
+index 5c90408..c8b7d14 100644
+--- a/src/rfc2131.c
++++ b/src/rfc2131.c
+@@ -1253,6 +1253,16 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
+ 	      /* pick up INIT-REBOOT events. */
+ 	      lease->flags |= LEASE_CHANGED;
+ 
++	      if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 0)))
++		{
++		  int len = sizeof(lease->req_options) - 1;
++		  if (option_len(opt) < len) {
++		    len = option_len(opt);
++		  }
++		  memcpy(lease->req_options, option_ptr(opt, 0), len);
++		  lease->req_options[len] = OPTION_END;
++		}
++
+ #ifdef HAVE_SCRIPT
+ 	      if (daemon->lease_change_command)
+ 		{