summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Giudici <fgiudici@redhat.com>2019-06-27 12:28:59 +0200
committerFrancesco Giudici <fgiudici@redhat.com>2019-07-05 15:15:11 +0200
commitf9314526d0e77f0e4a1ce886cbd9d29edbcbf1b2 (patch)
treec87c578d2bfdd2b9b5e543a71586dd8cd127eed0
parenteed205bff317469df846d6d5c3f9714f40ccd244 (diff)
downloadNetworkManager-f9314526d0e77f0e4a1ce886cbd9d29edbcbf1b2.tar.gz
dhcp/dhclient: expose the private_xyz labels for dhcp private options
alias the default "unknown_xyz" labels when found.
-rw-r--r--src/dhcp/nm-dhcp-client.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index e6ac217c56..9f585c5dc9 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -730,6 +730,23 @@ bytearray_variant_to_string (NMDhcpClient *self, GVariant *value, const char *ke
return converted;
}
+static int
+label_is_unknown_xyz (const char *label)
+{
+ if (!NM_STR_HAS_PREFIX (label, "unknown_"))
+ return -EINVAL;
+
+ label += NM_STRLEN ("unknown_");
+ if ( label[0] != '2'
+ || !g_ascii_isdigit (label[1])
+ || !g_ascii_isdigit (label[2])
+ || label[3] != '\0')
+ return -EINVAL;
+
+ return _nm_utils_ascii_str_to_int64 (label, 10, 224, 254, -EINVAL);
+}
+
+
#define OLD_TAG "old_"
#define NEW_TAG "new_"
@@ -753,14 +770,41 @@ maybe_add_option (NMDhcpClient *self,
"dhcp_message_type"))
return;
- if (g_str_has_prefix (key, NEW_TAG))
+ if (NM_STR_HAS_PREFIX (key, NEW_TAG))
key += NM_STRLEN (NEW_TAG);
- if (!key[0])
+ if (NM_STR_HAS_PREFIX (key, "private_") || !key[0])
return;
str_value = bytearray_variant_to_string (self, value, key);
- if (str_value)
+ if (str_value) {
+ int priv_opt_num;
+
g_hash_table_insert (hash, g_strdup (key), str_value);
+
+ /* dhclient has no special labels for private dhcp options: it uses "unknown_xyz"
+ * labels for that. We need to identify those to alias them to our "private_xyz"
+ * format unsed in the internal dchp plugins.
+ */
+ if ((priv_opt_num = label_is_unknown_xyz (key)) > 0) {
+ gs_free guint8 *check_val = NULL;
+ char *hex_str = NULL;
+ gsize len;
+
+ /* dhclient passes values from dhcp private options in its own "string" format:
+ * if the raw values are printable as ascii strings, it will pass the string
+ * representation; if the values are not printable as an ascii string, it will
+ * pass a string displaying the hex values (hex string). Try to enforce passing
+ * always an hex string, converting string representation if needed.
+ */
+ check_val = nm_utils_hexstr2bin_alloc (str_value, FALSE, TRUE, ":", 0, &len);
+ hex_str = nm_utils_bin2hexstr_full (check_val ?: (guint8 *) str_value,
+ check_val ? len : strlen (str_value),
+ ':', FALSE, NULL);
+ g_hash_table_insert (hash,
+ g_strdup_printf ("private_%d", priv_opt_num),
+ hex_str);
+ }
+ }
}
gboolean