diff options
author | Francesco Giudici <fgiudici@redhat.com> | 2019-06-27 12:28:59 +0200 |
---|---|---|
committer | Francesco Giudici <fgiudici@redhat.com> | 2019-07-05 15:15:11 +0200 |
commit | f9314526d0e77f0e4a1ce886cbd9d29edbcbf1b2 (patch) | |
tree | c87c578d2bfdd2b9b5e543a71586dd8cd127eed0 | |
parent | eed205bff317469df846d6d5c3f9714f40ccd244 (diff) | |
download | NetworkManager-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.c | 50 |
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 |