dhclient: read DUID from leasefiles
This commit is contained in:

committed by
Dan Williams

parent
dc518cf86b
commit
ab4bc03de2
@@ -328,3 +328,39 @@ error:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DUID_PREFIX "default-duid \""
|
||||||
|
|
||||||
|
GByteArray *
|
||||||
|
nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error)
|
||||||
|
{
|
||||||
|
GByteArray *duid = NULL;
|
||||||
|
char *contents;
|
||||||
|
char **line, **split, *p, *e;
|
||||||
|
|
||||||
|
if (!g_file_test (leasefile, G_FILE_TEST_EXISTS))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!g_file_get_contents (leasefile, &contents, NULL, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
split = g_strsplit_set (contents, "\n\r", -1);
|
||||||
|
for (line = split; line && *line && (duid == NULL); line++) {
|
||||||
|
p = g_strstrip (*line);
|
||||||
|
if (g_str_has_prefix (p, DUID_PREFIX)) {
|
||||||
|
p += strlen (DUID_PREFIX);
|
||||||
|
|
||||||
|
/* look for trailing "; */
|
||||||
|
e = p + strlen (p) - 2;
|
||||||
|
if (strcmp (e, "\";") != 0)
|
||||||
|
continue;
|
||||||
|
*e = '\0';
|
||||||
|
|
||||||
|
duid = nm_dhcp_dhclient_unescape_duid (p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (contents);
|
||||||
|
g_strfreev (split);
|
||||||
|
|
||||||
|
return duid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -38,5 +38,7 @@ char *nm_dhcp_dhclient_escape_duid (const GByteArray *duid);
|
|||||||
|
|
||||||
GByteArray *nm_dhcp_dhclient_unescape_duid (const char *duid);
|
GByteArray *nm_dhcp_dhclient_unescape_duid (const char *duid);
|
||||||
|
|
||||||
|
GByteArray *nm_dhcp_dhclient_read_duid (const char *leasefile, GError **error);
|
||||||
|
|
||||||
#endif /* NM_DHCP_DHCLIENT_UTILS_H */
|
#endif /* NM_DHCP_DHCLIENT_UTILS_H */
|
||||||
|
|
||||||
|
@@ -50,6 +50,7 @@ G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT)
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
const char *path;
|
const char *path;
|
||||||
char *conf_file;
|
char *conf_file;
|
||||||
|
const char *def_leasefile;
|
||||||
char *lease_file;
|
char *lease_file;
|
||||||
char *pid_file;
|
char *pid_file;
|
||||||
} NMDHCPDhclientPrivate;
|
} NMDHCPDhclientPrivate;
|
||||||
@@ -627,14 +628,75 @@ stop (NMDHCPClient *client, gboolean release, const GByteArray *duid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GByteArray *
|
||||||
|
get_duid (NMDHCPClient *client)
|
||||||
|
{
|
||||||
|
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
|
||||||
|
GByteArray *duid = NULL;
|
||||||
|
char *leasefile;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Look in interface-specific leasefile first for backwards compat */
|
||||||
|
leasefile = get_dhclient_leasefile (nm_dhcp_client_get_iface (client),
|
||||||
|
nm_dhcp_client_get_uuid (client),
|
||||||
|
TRUE);
|
||||||
|
nm_log_dbg (LOGD_DHCP, "Looking for DHCPv6 DUID in '%s'.", leasefile);
|
||||||
|
duid = nm_dhcp_dhclient_read_duid (leasefile, &error);
|
||||||
|
g_free (leasefile);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
nm_log_warn (LOGD_DHCP, "Failed to read leasefile '%s': (%d) %s",
|
||||||
|
leasefile,
|
||||||
|
error ? error->code : -1,
|
||||||
|
error ? error->message : "(unknown)");
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!duid && priv->def_leasefile) {
|
||||||
|
/* Otherwise read the default machine-wide DUID */
|
||||||
|
nm_log_dbg (LOGD_DHCP, "Looking for default DHCPv6 DUID in '%s'.", priv->def_leasefile);
|
||||||
|
duid = nm_dhcp_dhclient_read_duid (priv->def_leasefile, &error);
|
||||||
|
if (error) {
|
||||||
|
nm_log_warn (LOGD_DHCP, "Failed to read leasefile '%s': (%d) %s",
|
||||||
|
priv->def_leasefile,
|
||||||
|
error ? error->code : -1,
|
||||||
|
error ? error->message : "(unknown)");
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return our DUID, otherwise let the parent class make a default DUID */
|
||||||
|
return duid ? duid : NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->get_duid (client);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
|
|
||||||
|
static const char *def_leasefiles[] = {
|
||||||
|
SYSCONFDIR "/dhclient6.leases",
|
||||||
|
LOCALSTATEDIR "/lib/dhcp/dhclient6.leases",
|
||||||
|
LOCALSTATEDIR "/lib/dhclient/dhclient6.leases",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_dhcp_dhclient_init (NMDHCPDhclient *self)
|
nm_dhcp_dhclient_init (NMDHCPDhclient *self)
|
||||||
{
|
{
|
||||||
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
|
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
|
||||||
|
const char **iter = &def_leasefiles[0];
|
||||||
|
|
||||||
priv->path = nm_dhcp_dhclient_get_path (DHCLIENT_PATH);
|
priv->path = nm_dhcp_dhclient_get_path (DHCLIENT_PATH);
|
||||||
|
|
||||||
|
while (iter && *iter) {
|
||||||
|
if (g_file_test (*iter, G_FILE_TEST_EXISTS)) {
|
||||||
|
priv->def_leasefile = *iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback option */
|
||||||
|
if (!priv->def_leasefile)
|
||||||
|
priv->def_leasefile = SYSCONFDIR "/dhclient6.leases";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -663,5 +725,6 @@ nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class)
|
|||||||
client_class->ip4_start = ip4_start;
|
client_class->ip4_start = ip4_start;
|
||||||
client_class->ip6_start = ip6_start;
|
client_class->ip6_start = ip6_start;
|
||||||
client_class->stop = stop;
|
client_class->stop = stop;
|
||||||
|
client_class->get_duid = get_duid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user