]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd-network/sd-dhcp6-client.c
DHCP DUID, IAID configuration options
[thirdparty/systemd.git] / src / libsystemd-network / sd-dhcp6-client.c
index 0e7327b895a94acfb06f953fede1fe104ee438e4..ee4fb4fc1edba409fde6528709e4c51380e26ee4 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
@@ -35,6 +33,7 @@
 #include "in-addr-util.h"
 #include "network-internal.h"
 #include "random-util.h"
+#include "socket-util.h"
 #include "string-table.h"
 #include "util.h"
 
@@ -65,7 +64,7 @@ struct sd_dhcp6_client {
         uint8_t retransmit_count;
         sd_event_source *timeout_resend;
         sd_event_source *timeout_resend_expire;
-        sd_dhcp6_client_cb_t cb;
+        sd_dhcp6_client_callback_t cb;
         void *userdata;
         struct duid duid;
         size_t duid_len;
@@ -112,7 +111,7 @@ DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
 
 static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
 
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_cb_t cb, void *userdata) {
+int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_callback_t cb, void *userdata) {
         assert_return(client, -EINVAL);
 
         client->cb = cb;
@@ -181,41 +180,29 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
         return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
 }
 
-int sd_dhcp6_client_set_duid(
-                sd_dhcp6_client *client,
-                uint16_t type,
-                uint8_t *duid, size_t duid_len) {
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
+                             uint8_t *duid, size_t duid_len) {
+        int r;
         assert_return(client, -EINVAL);
-        assert_return(duid, -EINVAL);
-        assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
-
         assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
 
-        switch (type) {
-        case DHCP6_DUID_LLT:
-                if (duid_len <= sizeof(client->duid.llt))
-                        return -EINVAL;
-                break;
-        case DHCP6_DUID_EN:
-                if (duid_len != sizeof(client->duid.en))
-                        return -EINVAL;
-                break;
-        case DHCP6_DUID_LL:
-                if (duid_len <= sizeof(client->duid.ll))
-                        return -EINVAL;
-                break;
-        case DHCP6_DUID_UUID:
-                if (duid_len != sizeof(client->duid.uuid))
-                        return -EINVAL;
-                break;
-        default:
-                /* accept unknown type in order to be forward compatible */
-                break;
+        if (duid_len > 0) {
+                r = dhcp_validate_duid_len(duid_type, duid_len);
+                if (r < 0)
+                        return r;
+                client->duid.type = htobe16(duid_type);
+                memcpy(&client->duid.raw.data, duid, duid_len);
+                client->duid_len = duid_len + sizeof(client->duid.type);
         }
 
-        client->duid.type = htobe16(type);
-        memcpy(&client->duid.raw.data, duid, duid_len);
-        client->duid_len = duid_len + sizeof(client->duid.type);
+        return 0;
+}
+
+int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
+        assert_return(client, -EINVAL);
+        assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
+
+        client->ia_na.id = htobe32(iaid);
 
         return 0;
 }
@@ -893,18 +880,16 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
         sd_dhcp6_client *client = userdata;
         DHCP6_CLIENT_DONT_DESTROY(client);
         _cleanup_free_ DHCP6Message *message = NULL;
-        int r, buflen, len;
+        ssize_t buflen, len;
+        int r = 0;
 
         assert(s);
         assert(client);
         assert(client->event);
 
-        r = ioctl(fd, FIONREAD, &buflen);
-        if (r < 0)
-                return -errno;
-        else if (buflen < 0)
-                /* This really should not happen */
-                return -EIO;
+        buflen = next_datagram_size_fd(fd);
+        if (buflen < 0)
+                return buflen;
 
         message = malloc(buflen);
         if (!message)
@@ -1207,7 +1192,7 @@ error:
         return r;
 }
 
-int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int priority) {
+int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority) {
         int r;
 
         assert_return(client, -EINVAL);