dhcp/dhclient: expose the private_xyz labels for dhcp private options

alias the default "unknown_xyz" labels when found.
This commit is contained in:
Francesco Giudici 2019-06-27 12:28:59 +02:00
parent eed205bff3
commit f9314526d0

View file

@ -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