networkd: send hostname to dhcp server
Send hostname (option 12) in DISCOVER and REQUEST messages so the DHCP server could use it to register with dynamic DNS and such. To opt-out of this behaviour set SendHostname to false in [DHCP] section of .network file [tomegun: rebased, made sure a failing set_hostname is a noop and moved config from DHCPv4 to DHCP]
This commit is contained in:
parent
0a8a0fad01
commit
4cc7a82c94
|
@ -404,6 +404,13 @@
|
||||||
be used on the current link. Defaults to false.</para>
|
be used on the current link. Defaults to false.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>SendHostname=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>When true (the default), the machine's hostname will be sent to the DHCP
|
||||||
|
server</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>UseHostname=</varname></term>
|
<term><varname>UseHostname=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct sd_dhcp_client {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
struct ether_addr mac_addr;
|
struct ether_addr mac_addr;
|
||||||
} _packed_ client_id;
|
} _packed_ client_id;
|
||||||
|
char *hostname;
|
||||||
uint32_t xid;
|
uint32_t xid;
|
||||||
usec_t start_time;
|
usec_t start_time;
|
||||||
uint16_t secs;
|
uint16_t secs;
|
||||||
|
@ -178,6 +179,27 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
|
||||||
|
const char *hostname) {
|
||||||
|
char *new_hostname = NULL;
|
||||||
|
|
||||||
|
assert_return(client, -EINVAL);
|
||||||
|
|
||||||
|
if (streq_ptr(client->hostname, hostname))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (hostname) {
|
||||||
|
new_hostname = strdup(hostname);
|
||||||
|
if (!new_hostname)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(client->hostname);
|
||||||
|
client->hostname = new_hostname;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
assert_return(ret, -EINVAL);
|
assert_return(ret, -EINVAL);
|
||||||
|
@ -386,6 +408,17 @@ static int client_send_discover(sd_dhcp_client *client) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* it is unclear from RFC 2131 if client should send hostname in
|
||||||
|
DHCPDISCOVER but dhclient does and so we do as well
|
||||||
|
*/
|
||||||
|
if (client->hostname) {
|
||||||
|
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
||||||
|
DHCP_OPTION_HOST_NAME,
|
||||||
|
strlen(client->hostname), client->hostname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
|
||||||
DHCP_OPTION_END, 0, NULL);
|
DHCP_OPTION_END, 0, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -477,6 +510,14 @@ static int client_send_request(sd_dhcp_client *client) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client->hostname) {
|
||||||
|
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
||||||
|
DHCP_OPTION_HOST_NAME,
|
||||||
|
strlen(client->hostname), client->hostname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
||||||
DHCP_OPTION_END, 0, NULL);
|
DHCP_OPTION_END, 0, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -1364,6 +1405,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
|
||||||
sd_dhcp_lease_unref(client->lease);
|
sd_dhcp_lease_unref(client->lease);
|
||||||
|
|
||||||
free(client->req_opts);
|
free(client->req_opts);
|
||||||
|
free(client->hostname);
|
||||||
free(client);
|
free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <netinet/ether.h>
|
#include <netinet/ether.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "networkd.h"
|
#include "networkd.h"
|
||||||
#include "libudev-private.h"
|
#include "libudev-private.h"
|
||||||
|
@ -1927,6 +1928,18 @@ static int link_enter_enslave(Link *link) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure the hostname is not "localhost" */
|
||||||
|
static bool is_localhost(const char *hostname) {
|
||||||
|
assert(hostname);
|
||||||
|
|
||||||
|
return streq(hostname, "localhost") ||
|
||||||
|
streq(hostname, "localhost.") ||
|
||||||
|
endswith(hostname, ".localhost") ||
|
||||||
|
endswith(hostname, ".localhost.") ||
|
||||||
|
endswith(hostname, ".localdomain") ||
|
||||||
|
endswith(hostname, ".localdomain.");
|
||||||
|
}
|
||||||
|
|
||||||
static int link_configure(Link *link) {
|
static int link_configure(Link *link) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -1992,6 +2005,7 @@ static int link_configure(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link->network->dhcp_routes) {
|
if (link->network->dhcp_routes) {
|
||||||
r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
|
r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -2000,6 +2014,18 @@ static int link_configure(Link *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link->network->dhcp_sendhost) {
|
||||||
|
_cleanup_free_ char *hostname = gethostname_malloc();
|
||||||
|
if (!hostname)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!is_localhost(hostname)) {
|
||||||
|
r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link->network->dhcp_server) {
|
if (link->network->dhcp_server) {
|
||||||
|
|
|
@ -47,11 +47,12 @@ DHCP.UseDNS, config_parse_bool, 0,
|
||||||
DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
|
DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
|
||||||
DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
|
DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
|
||||||
DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domainname)
|
DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domainname)
|
||||||
|
DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes)
|
||||||
|
DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost)
|
||||||
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
|
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
|
||||||
/* backwards compatibility */
|
/* backwards compatibility: do not add new entries to this section */
|
||||||
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns)
|
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns)
|
||||||
DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
|
DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu)
|
||||||
DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
|
DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname)
|
||||||
DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domainname)
|
DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domainname)
|
||||||
DHCPv4.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes)
|
|
||||||
DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
|
DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
|
||||||
|
|
|
@ -90,6 +90,7 @@ static int network_load_one(Manager *manager, const char *filename) {
|
||||||
network->dhcp_hostname = true;
|
network->dhcp_hostname = true;
|
||||||
network->dhcp_domainname = true;
|
network->dhcp_domainname = true;
|
||||||
network->dhcp_routes = true;
|
network->dhcp_routes = true;
|
||||||
|
network->dhcp_sendhost = true;
|
||||||
|
|
||||||
r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0DHCPv4\0", config_item_perf_lookup,
|
r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0DHCPv4\0", config_item_perf_lookup,
|
||||||
(void*) network_network_gperf_lookup, false, false, network);
|
(void*) network_network_gperf_lookup, false, false, network);
|
||||||
|
|
|
@ -169,6 +169,7 @@ struct Network {
|
||||||
bool dhcp_mtu;
|
bool dhcp_mtu;
|
||||||
bool dhcp_hostname;
|
bool dhcp_hostname;
|
||||||
bool dhcp_domainname;
|
bool dhcp_domainname;
|
||||||
|
bool dhcp_sendhost;
|
||||||
bool dhcp_critical;
|
bool dhcp_critical;
|
||||||
bool dhcp_routes;
|
bool dhcp_routes;
|
||||||
bool ipv4ll;
|
bool ipv4ll;
|
||||||
|
|
|
@ -51,6 +51,7 @@ int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
|
||||||
int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
|
int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
|
||||||
int sd_dhcp_client_set_mac(sd_dhcp_client *client,
|
int sd_dhcp_client_set_mac(sd_dhcp_client *client,
|
||||||
const struct ether_addr *addr);
|
const struct ether_addr *addr);
|
||||||
|
int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
|
||||||
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
|
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
|
||||||
|
|
||||||
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
||||||
|
|
Loading…
Reference in a new issue