[systemd-devel] [PATCH v2] networkd: send hostname to dhcp server

Tom Gundersen teg at jklm.no
Tue Jul 1 13:04:12 PDT 2014


On Tue, Jul 1, 2014 at 8:58 PM, Eugene Yakubovich
<eugene.yakubovich at coreos.com> wrote:
> 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 [DHCPv4]
> section of .network file

Pushed with minor modifications. Please check that it still works ok for you.

Thanks!

Tom

>  man/systemd.network.xml                  |  7 ++++++
>  src/libsystemd-network/sd-dhcp-client.c  | 41 ++++++++++++++++++++++++++++++++
>  src/network/networkd-link.c              | 25 +++++++++++++++++++
>  src/network/networkd-network-gperf.gperf |  1 +
>  src/network/networkd-network.c           |  1 +
>  src/network/networkd.h                   |  1 +
>  src/systemd/sd-dhcp-client.h             |  1 +
>  7 files changed, 77 insertions(+)
>
> diff --git a/man/systemd.network.xml b/man/systemd.network.xml
> index 8b2dd2f..906086b 100644
> --- a/man/systemd.network.xml
> +++ b/man/systemd.network.xml
> @@ -380,6 +380,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 1603c41..c278bb7 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,26 @@ 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) {
> +
> +        assert_return(client, -EINVAL);
> +
> +        if (streq_ptr(client->hostname, hostname))
> +                return 0;
> +
> +        free(client->hostname);
> +
> +        if (hostname) {
> +                client->hostname = strdup(hostname);
> +                if (!client->hostname)
> +                        return -ENOMEM;
> +        } else
> +                client->hostname = NULL;
> +
> +        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 +407,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 +509,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)
> @@ -1363,6 +1403,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 9296a59..e573502 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"
> @@ -1846,6 +1847,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;
>
> @@ -1911,6 +1924,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 469e028..6abef51 100644
> --- a/src/network/networkd-network-gperf.gperf
> +++ b/src/network/networkd-network-gperf.gperf
> @@ -48,4 +48,5 @@ DHCPv4.UseDNS,               config_parse_bool,                  0,
>  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.SendHostname,         config_parse_bool,                  0,                             offsetof(Network, dhcp_sendhost)
>  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 8e7cdf6..0291b5a 100644
> --- a/src/network/networkd-network.c
> +++ b/src/network/networkd-network.c
> @@ -89,6 +89,7 @@ static int network_load_one(Manager *manager, const char *filename) {
>          network->dhcp_dns = true;
>          network->dhcp_hostname = true;
>          network->dhcp_domainname = 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 b7b1d90..3667e46 100644
> --- a/src/network/networkd.h
> +++ b/src/network/networkd.h
> @@ -159,6 +159,7 @@ struct Network {
>          bool dhcp_mtu;
>          bool dhcp_hostname;
>          bool dhcp_domainname;
> +        bool dhcp_sendhost;
>          bool dhcp_critical;
>          bool ipv4ll;
>          bool dhcp6;
> diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
> index 5818ec4..7b5b938 100644
> --- a/src/systemd/sd-dhcp-client.h
> +++ b/src/systemd/sd-dhcp-client.h
> @@ -50,6 +50,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);
> --
> 1.9.1
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel


More information about the systemd-devel mailing list