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

Eugene Yakubovich eugene.yakubovich at coreos.com
Mon Jun 30 16:52:21 PDT 2014


Send hostname (option 12) in DISCOVER and REQUEST messages so the
DHCP server could use it to register with dynamic DNS and such.
---
 src/libsystemd-network/sd-dhcp-client.c | 35 +++++++++++++++++++++++++++++++++
 src/network/networkd-link.c             | 26 ++++++++++++++++++++++++
 src/systemd/sd-dhcp-client.h            |  1 +
 3 files changed, 62 insertions(+)

diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 1603c41..44a5e8a 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,20 @@ 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);
+        assert_return(hostname, -EINVAL);
+
+        if (client->hostname && streq(client->hostname, hostname) )
+                return 0;
+
+        client->hostname = strdup(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 +401,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 +503,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 +1397,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..9d849a0 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,19 @@ static int link_enter_enslave(Link *link) {
         return 0;
 }
 
+/* make sure the hostname is not "localhost" */
+static bool is_localhost(const char *hostname) {
+        char *hostend;
+
+        assert(hostname);
+
+        hostend = strchr(hostname, '.');
+        if (hostend)
+                return strneq(hostname, "localhost", (hostend - hostname));
+        else
+                return streq(hostname, "localhost");
+}
+
 static int link_configure(Link *link) {
         int r;
 
@@ -1886,6 +1900,8 @@ static int link_configure(Link *link) {
         }
 
         if (link->network->dhcp) {
+                char hostname[HOST_NAME_MAX];
+
                 r = sd_dhcp_client_new(&link->dhcp_client);
                 if (r < 0)
                         return r;
@@ -1911,6 +1927,16 @@ static int link_configure(Link *link) {
                         if (r < 0)
                                 return r;
                 }
+
+                r = gethostname(hostname, sizeof(hostname));
+                if (r < 0)
+                        return r;
+
+                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/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



More information about the systemd-devel mailing list