diff options
author | Eugene Yakubovich <eugene.yakubovich@coreos.com> | 2014-07-01 11:58:49 -0700 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-07-01 22:02:25 +0200 |
commit | 4cc7a82c9490a3c5ae03b1d6d168ce40ba499e23 (patch) | |
tree | 0b806eddc7563072cb1398ae602ced46ee840b4c | |
parent | 0a8a0fad010018be0f46d1c2e077ade0eb27c7db (diff) |
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]
-rw-r--r-- | man/systemd.network.xml | 7 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-client.c | 42 | ||||
-rw-r--r-- | src/network/networkd-link.c | 26 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 5 | ||||
-rw-r--r-- | src/network/networkd-network.c | 1 | ||||
-rw-r--r-- | src/network/networkd.h | 1 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-client.h | 1 |
7 files changed, 81 insertions, 2 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 707ced13d2..2b0eb567be 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -405,6 +405,13 @@ </listitem> </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> <term><varname>UseHostname=</varname></term> <listitem> <para>When true (the default), the hostname received from the DHCP server diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 8e9f5bd827..d8a9d20e4c 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -56,6 +56,7 @@ struct sd_dhcp_client { uint8_t type; struct ether_addr mac_addr; } _packed_ client_id; + char *hostname; uint32_t xid; usec_t start_time; uint16_t secs; @@ -178,6 +179,27 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, 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) { assert_return(client, -EINVAL); assert_return(ret, -EINVAL); @@ -386,6 +408,17 @@ static int client_send_discover(sd_dhcp_client *client) { 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, DHCP_OPTION_END, 0, NULL); if (r < 0) @@ -477,6 +510,14 @@ static int client_send_request(sd_dhcp_client *client) { 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, DHCP_OPTION_END, 0, NULL); if (r < 0) @@ -1364,6 +1405,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { sd_dhcp_lease_unref(client->lease); free(client->req_opts); + free(client->hostname); free(client); } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index a523a3e9b2..3324276bcc 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -21,6 +21,7 @@ #include <netinet/ether.h> #include <linux/if.h> +#include <unistd.h> #include "networkd.h" #include "libudev-private.h" @@ -1927,6 +1928,18 @@ static int link_enter_enslave(Link *link) { 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) { int r; @@ -1992,6 +2005,7 @@ static int link_configure(Link *link) { if (r < 0) return r; } + if (link->network->dhcp_routes) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE); if (r < 0) @@ -2000,6 +2014,18 @@ static int link_configure(Link *link) { if (r < 0) 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) { diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index b6d52e7335..3aaae4c94b 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -47,11 +47,12 @@ DHCP.UseDNS, config_parse_bool, 0, DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) 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) -/* backwards compatibility */ +/* backwards compatibility: do not add new entries to this section */ DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) 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) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index f60f7c812c..9ab4f23068 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -90,6 +90,7 @@ static int network_load_one(Manager *manager, const char *filename) { network->dhcp_hostname = true; network->dhcp_domainname = 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, (void*) network_network_gperf_lookup, false, false, network); diff --git a/src/network/networkd.h b/src/network/networkd.h index d1b0bb72ae..c2b88acd61 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -169,6 +169,7 @@ struct Network { bool dhcp_mtu; bool dhcp_hostname; bool dhcp_domainname; + bool dhcp_sendhost; bool dhcp_critical; bool dhcp_routes; bool ipv4ll; diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 0ed7d0f135..c3ea0592f6 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -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_mac(sd_dhcp_client *client, 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_stop(sd_dhcp_client *client); |