dhcpcd-6.8.2: Change vendor_encapsulated_options to binhex

This is the same CL as https://chromium-review.googlesource.com/#/c/320426/ and
is applied here to work correctly on Brillo

Make option vendor_encapsulated_options of type binhex and pass
VendorEncapsulatedOptions on dbus as a byte array

BUG: chromium:574578
TEST=run `dbus-monitor --system \
 "type=signal,path=/org/chromium/dhcpcd,interface=org.chromium.dhcpcd,arg1='BOUND'"`
 and check that VendorEncapsulatedOptions is sent as array of bytes

Change-Id: Icd9c6c1f73d5eb46a8eb04204e6d2cb039a38f45
diff --git a/dbus/dbus-dict.c b/dbus/dbus-dict.c
index aeee57c..995b82d 100644
--- a/dbus/dbus-dict.c
+++ b/dbus/dbus-dict.c
@@ -29,6 +29,7 @@
 
 #include <ctype.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <syslog.h>
 
@@ -167,6 +168,50 @@
 }
 
 static int
+append_config_byte_array(DBusMessageIter *entry, const char *data)
+{
+	DBusMessageIter var, array;
+	dbus_bool_t ok = TRUE;
+	uint8_t u8, u8_2;
+	size_t len;
+	const char *it, *end;
+	const char *tsa, *ts;
+
+	tsa = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
+	ts = DBUS_TYPE_BYTE_AS_STRING;
+
+	dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT, tsa, &var);
+	dbus_message_iter_open_container(&var, DBUS_TYPE_ARRAY, ts, &array);
+
+	len = strlen(data);
+	it = data;
+	end = data + len;
+
+	/* "a12" is treated as "0a12" */
+	if (len & 1) {
+		ok = (sscanf(it++, "%1hhx", &u8) == 1) &&
+			dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE,
+						       &u8);
+	}
+
+	while (ok && it < end) {
+		/* sscanf("1z", "%2hhx", &u8) will store 0x01 in u8 and
+		 * will return 1 */
+		ok = (sscanf(it++, "%1hhx", &u8) == 1) &&
+			(sscanf(it++, "%1hhx", &u8_2) == 1);
+		if (!ok)
+			break;
+
+		u8 = (u8 << 4) | u8_2;
+		ok = dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE, &u8);
+	}
+
+	dbus_message_iter_close_container(&var, &array);
+	dbus_message_iter_close_container(entry, &var);
+	return ok ? 0 : -1;
+}
+
+static int
 append_config_array(DBusMessageIter *entry, int type, const char *data)
 {
 	int retval;
@@ -177,6 +222,9 @@
 	dbus_uint32_t u32;
 	struct in_addr in;
 
+	if (type == DBUS_TYPE_BYTE)
+		return append_config_byte_array(entry, data);
+
 	switch (type) {
 	case DBUS_TYPE_STRING:
 		tsa = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
diff --git a/dbus/rpc-dbus.c b/dbus/rpc-dbus.c
index ea380c4..438aa00 100644
--- a/dbus/rpc-dbus.c
+++ b/dbus/rpc-dbus.c
@@ -160,7 +160,7 @@
 	{ "nis_domain=", DBUS_TYPE_STRING, 0, "NISDomain" },
 	{ "nis_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NISServers" },
 	{ "ntp_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NTPServers" },
-	{ "vendor_encapsulated_options=", DBUS_TYPE_STRING, 0,
+	{ "vendor_encapsulated_options=", DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
 	  "VendorEncapsulatedOptions" },
 	{ "netbios_name_servers=" ,DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
 	  "NetBIOSNameServers" },
diff --git a/dhcpcd-definitions.conf b/dhcpcd-definitions.conf
index ad37c2b..0e5aa3b 100644
--- a/dhcpcd-definitions.conf
+++ b/dhcpcd-definitions.conf
@@ -58,7 +58,7 @@
 define 40	string			nis_domain
 define 41	array ipaddress		nis_servers
 define 42	array ipaddress		ntp_servers
-define 43	string			vendor_encapsulated_options
+define 43	binhex			vendor_encapsulated_options
 define 44	array ipaddress		netbios_name_servers
 define 45	ipaddress		netbios_dd_server
 define 46	byte			netbios_node_type