From: Marc-André Lureau Date: Fri, 22 May 2020 09:30:49 +0000 (+0200) Subject: sd-dhcp-client: add sd_dhcp_client_id_to_string() X-Git-Tag: v246-rc1~207^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7be3261222875167267348d43ad46b5e33b6535e;p=thirdparty%2Fsystemd.git sd-dhcp-client: add sd_dhcp_client_id_to_string() Add a human-friendly pretty-printer for client ID. --- diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index eaf5c78df04..d5f25d5a194 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 85b49bae74b..ac3b5b369c1 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,