summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2020-05-22 11:30:49 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2020-06-04 11:16:15 +0200
commit7be3261222875167267348d43ad46b5e33b6535e (patch)
tree9f963c944f68b0fc536b8ffc92de9ed2c040cef0 /src
parentaaec2d7b9b4756e5600d132e1a179f8bdce99945 (diff)
downloadsystemd-7be3261222875167267348d43ad46b5e33b6535e.tar.gz
sd-dhcp-client: add sd_dhcp_client_id_to_string()
Add a human-friendly pretty-printer for client ID.
Diffstat (limited to 'src')
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c55
-rw-r--r--src/systemd/sd-dhcp-client.h2
2 files changed, 57 insertions, 0 deletions
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index eaf5c78df0..d5f25d5a19 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -27,6 +27,7 @@
#include "random-util.h"
#include "string-util.h"
#include "strv.h"
+#include "utf8.h"
#include "web-util.h"
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
@@ -153,6 +154,60 @@ static int client_receive_message_udp(
void *userdata);
static void client_stop(sd_dhcp_client *client, int error);
+int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret) {
+ const sd_dhcp_client_id *client_id = data;
+ _cleanup_free_ char *t = NULL;
+ int r = 0;
+
+ assert_return(data, -EINVAL);
+ assert_return(len >= 1, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ len -= 1;
+ if (len > MAX_CLIENT_ID_LEN)
+ return -EINVAL;
+
+ switch (client_id->type) {
+ case 0:
+ if (utf8_is_printable((char *) client_id->gen.data, len))
+ r = asprintf(&t, "%.*s", (int) len, client_id->gen.data);
+ else
+ r = asprintf(&t, "DATA");
+ break;
+ case 1:
+ if (len != sizeof_field(sd_dhcp_client_id, eth))
+ return -EINVAL;
+
+ r = asprintf(&t, "%x:%x:%x:%x:%x:%x",
+ client_id->eth.haddr[0],
+ client_id->eth.haddr[1],
+ client_id->eth.haddr[2],
+ client_id->eth.haddr[3],
+ client_id->eth.haddr[4],
+ client_id->eth.haddr[5]);
+ break;
+ case 2 ... 254:
+ r = asprintf(&t, "ARP/LL");
+ break;
+ case 255:
+ if (len < 6)
+ return -EINVAL;
+
+ uint32_t iaid = be32toh(client_id->ns.iaid);
+ uint16_t duid_type = be16toh(client_id->ns.duid.type);
+ if (dhcp_validate_duid_len(duid_type, len - 6, true) < 0)
+ return -EINVAL;
+
+ r = asprintf(&t, "IAID:0x%x/DUID", iaid);
+ break;
+ }
+
+ if (r < 0)
+ return -ENOMEM;
+ *ret = TAKE_PTR(t);
+ return 0;
+}
+
int sd_dhcp_client_set_callback(
sd_dhcp_client *client,
sd_dhcp_client_callback_t cb,
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index 85b49bae74..ac3b5b369c 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -205,6 +205,8 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
* options when using RFC7844 Anonymity Profiles */
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize);
+int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret);
+
int sd_dhcp_client_attach_event(
sd_dhcp_client *client,
sd_event *event,