diff --git a/src/libsystemd-network/dhcp-client-id-internal.h b/src/libsystemd-network/dhcp-client-id-internal.h new file mode 100644 index 0000000000..eb7b1847e6 --- /dev/null +++ b/src/libsystemd-network/dhcp-client-id-internal.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "sd-dhcp-client-id.h" + +#include "dhcp-duid-internal.h" +#include "macro.h" +#include "sparse-endian.h" + +/* RFC 2132 section 9.14: its minimum length is 2. + * Note, its maximum is not mentioend in the RFC. Hence, 255. */ +#define MIN_CLIENT_ID_LEN 2 +#define MAX_CLIENT_ID_LEN 255 +#define MIN_CLIENT_ID_DATA_LEN (MIN_CLIENT_ID_LEN - sizeof(uint8_t)) +#define MAX_CLIENT_ID_DATA_LEN (MAX_CLIENT_ID_LEN - sizeof(uint8_t)) + +typedef struct sd_dhcp_client_id { + size_t size; + union { + struct { + uint8_t type; + union { + struct { + /* 0: Generic (non-LL) (RFC 2132) */ + uint8_t data[MAX_CLIENT_ID_DATA_LEN]; + } _packed_ gen; + struct { + /* 1: Ethernet Link-Layer (RFC 2132) */ + uint8_t haddr[ETH_ALEN]; + } _packed_ eth; + struct { + /* 2 - 254: ARP/Link-Layer (RFC 2132) */ + uint8_t haddr[0]; + } _packed_ ll; + struct { + /* 255: Node-specific (RFC 4361) */ + be32_t iaid; + struct duid duid; + } _packed_ ns; + uint8_t data[MAX_CLIENT_ID_DATA_LEN]; + }; + } _packed_ id; + uint8_t raw[MAX_CLIENT_ID_LEN]; + }; +} sd_dhcp_client_id; + +static inline bool client_id_size_is_valid(size_t size) { + return size >= MIN_CLIENT_ID_LEN && size <= MAX_CLIENT_ID_LEN; +} + +static inline bool client_id_data_size_is_valid(size_t size) { + return size >= MIN_CLIENT_ID_DATA_LEN && size <= MAX_CLIENT_ID_DATA_LEN; +} diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index a3d8bb45b3..b7bc142ef7 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -8,6 +8,7 @@ #include "sd-dhcp-client.h" #include "alloc-util.h" +#include "dhcp-client-id-internal.h" #include "dhcp-option.h" #include "list.h" #include "time-util.h" @@ -67,8 +68,7 @@ struct sd_dhcp_lease { char *root_path; char *captive_portal; - void *client_id; - size_t client_id_len; + sd_dhcp_client_id client_id; void *vendor_specific; size_t vendor_specific_len; @@ -92,7 +92,7 @@ int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const vo void dhcp_lease_set_timestamp(sd_dhcp_lease *lease, const triple_timestamp *timestamp); int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease); -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len); +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const sd_dhcp_client_id *client_id); #define dhcp_lease_unref_and_replace(a, b) \ unref_and_replace_full(a, b, sd_dhcp_lease_ref, sd_dhcp_lease_unref) diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build index 510b0ed99e..33ab5f7f8c 100644 --- a/src/libsystemd-network/meson.build +++ b/src/libsystemd-network/meson.build @@ -15,6 +15,7 @@ sources = files( 'ndisc-router.c', 'network-common.c', 'network-internal.c', + 'sd-dhcp-client-id.c', 'sd-dhcp-client.c', 'sd-dhcp-duid.c', 'sd-dhcp-lease.c', diff --git a/src/libsystemd-network/sd-dhcp-client-id.c b/src/libsystemd-network/sd-dhcp-client-id.c new file mode 100644 index 0000000000..03dca43822 --- /dev/null +++ b/src/libsystemd-network/sd-dhcp-client-id.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "alloc-util.h" +#include "dhcp-client-id-internal.h" +#include "unaligned.h" +#include "utf8.h" + +int sd_dhcp_client_id_clear(sd_dhcp_client_id *client_id) { + assert_return(client_id, -EINVAL); + + *client_id = (sd_dhcp_client_id) {}; + return 0; +} + +int sd_dhcp_client_id_is_set(const sd_dhcp_client_id *client_id) { + if (!client_id) + return false; + + return client_id_size_is_valid(client_id->size); +} + +int sd_dhcp_client_id_get(const sd_dhcp_client_id *client_id, uint8_t *ret_type, const void **ret_data, size_t *ret_size) { + assert_return(sd_dhcp_client_id_is_set(client_id), -EINVAL); + assert_return(ret_type, -EINVAL); + assert_return(ret_data, -EINVAL); + assert_return(ret_size, -EINVAL); + + *ret_type = client_id->id.type; + *ret_data = client_id->id.data; + *ret_size = client_id->size - offsetof(typeof(client_id->id), data); + return 0; +} + +int sd_dhcp_client_id_get_raw(const sd_dhcp_client_id *client_id, const void **ret_data, size_t *ret_size) { + assert_return(sd_dhcp_client_id_is_set(client_id), -EINVAL); + assert_return(ret_data, -EINVAL); + assert_return(ret_size, -EINVAL); + + /* Unlike sd_dhcp_client_id_get(), this returns whole client ID including its type. */ + + *ret_data = client_id->raw; + *ret_size = client_id->size; + return 0; +} + +int sd_dhcp_client_id_set( + sd_dhcp_client_id *client_id, + uint8_t type, + const void *data, + size_t data_size) { + + assert_return(client_id, -EINVAL); + assert_return(data, -EINVAL); + assert_return(client_id_data_size_is_valid(data_size), -EINVAL); + + client_id->id.type = type; + memcpy(client_id->id.data, data, data_size); + + client_id->size = offsetof(typeof(client_id->id), data) + data_size; + return 0; +} + +int sd_dhcp_client_id_set_raw( + sd_dhcp_client_id *client_id, + const void *data, + size_t data_size) { + + assert_return(client_id, -EINVAL); + assert_return(data, -EINVAL); + assert_return(client_id_size_is_valid(data_size), -EINVAL); + + /* Unlike sd_dhcp_client_id_set(), this takes whole client ID including its type. */ + + memcpy(client_id->raw, data, data_size); + + client_id->size = data_size; + return 0; +} + +int sd_dhcp_client_id_set_iaid_duid( + sd_dhcp_client_id *client_id, + uint32_t iaid, + sd_dhcp_duid *duid) { + + assert_return(client_id, -EINVAL); + assert_return(duid, -EINVAL); + assert_return(sd_dhcp_duid_is_set(duid), -ESTALE); + + client_id->id.type = 255; + unaligned_write_be32(&client_id->id.ns.iaid, iaid); + memcpy(&client_id->id.ns.duid, &duid->duid, duid->size); + + client_id->size = offsetof(typeof(client_id->id), ns.duid) + duid->size; + return 0; +} + +int sd_dhcp_client_id_to_string(const sd_dhcp_client_id *client_id, char **ret) { + _cleanup_free_ char *t = NULL; + size_t len; + int r; + + assert_return(sd_dhcp_client_id_is_set(client_id), -EINVAL); + assert_return(ret, -EINVAL); + + len = client_id->size - offsetof(typeof(client_id->id), data); + + switch (client_id->id.type) { + case 0: + if (utf8_is_printable((char *) client_id->id.gen.data, len)) + r = asprintf(&t, "%.*s", (int) len, client_id->id.gen.data); + else + r = asprintf(&t, "DATA"); + break; + case 1: + if (len == sizeof_field(sd_dhcp_client_id, id.eth)) + r = asprintf(&t, "%02x:%02x:%02x:%02x:%02x:%02x", + client_id->id.eth.haddr[0], + client_id->id.eth.haddr[1], + client_id->id.eth.haddr[2], + client_id->id.eth.haddr[3], + client_id->id.eth.haddr[4], + client_id->id.eth.haddr[5]); + else + r = asprintf(&t, "ETHER"); + break; + case 2 ... 254: + r = asprintf(&t, "ARP/LL"); + break; + case 255: + if (len < sizeof(uint32_t)) + r = asprintf(&t, "IAID/DUID"); + else { + uint32_t iaid = be32toh(client_id->id.ns.iaid); + /* TODO: check and stringify DUID */ + r = asprintf(&t, "IAID:0x%x/DUID", iaid); + } + break; + } + if (r < 0) + return -ENOMEM; + + *ret = TAKE_PTR(t); + return 0; +} + +int sd_dhcp_client_id_to_string_from_raw(const void *data, size_t data_size, char **ret) { + sd_dhcp_client_id client_id; + int r; + + assert_return(data, -EINVAL); + assert_return(client_id_size_is_valid(data_size), -EINVAL); + assert_return(ret, -EINVAL); + + r = sd_dhcp_client_id_set_raw(&client_id, data, data_size); + if (r < 0) + return r; + + return sd_dhcp_client_id_to_string(&client_id, ret); +} diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 8e370f1d7e..dc1c17035d 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -15,8 +15,8 @@ #include "alloc-util.h" #include "device-util.h" +#include "dhcp-client-id-internal.h" #include "dhcp-client-internal.h" -#include "dhcp-duid-internal.h" #include "dhcp-lease-internal.h" #include "dhcp-network.h" #include "dhcp-option.h" @@ -39,7 +39,6 @@ #include "utf8.h" #include "web-util.h" -#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */ #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN) #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC) @@ -48,32 +47,6 @@ #define TRANSIENT_FAILURE_ATTEMPTS 3 /* Arbitrary limit: how many attempts are considered enough to report * transient failure. */ -typedef struct sd_dhcp_client_id { - uint8_t type; - union { - struct { - /* 0: Generic (non-LL) (RFC 2132) */ - uint8_t data[MAX_CLIENT_ID_LEN]; - } _packed_ gen; - struct { - /* 1: Ethernet Link-Layer (RFC 2132) */ - uint8_t haddr[ETH_ALEN]; - } _packed_ eth; - struct { - /* 2 - 254: ARP/Link-Layer (RFC 2132) */ - uint8_t haddr[0]; - } _packed_ ll; - struct { - /* 255: Node-specific (RFC 4361) */ - be32_t iaid; - struct duid duid; - } _packed_ ns; - struct { - uint8_t data[MAX_CLIENT_ID_LEN]; - } _packed_ raw; - }; -} _packed_ sd_dhcp_client_id; - struct sd_dhcp_client { unsigned n_ref; @@ -100,7 +73,6 @@ struct sd_dhcp_client { struct hw_addr_data bcast_addr; uint16_t arp_type; sd_dhcp_client_id client_id; - size_t client_id_len; char *hostname; char *vendor_class_identifier; char *mudurl; @@ -178,58 +150,6 @@ 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)) - r = asprintf(&t, "%02x:%02x:%02x:%02x:%02x:%02x", - 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]); - else - r = asprintf(&t, "ETHER"); - break; - case 2 ... 254: - r = asprintf(&t, "ARP/LL"); - break; - case 255: - if (len < sizeof(uint32_t)) - r = asprintf(&t, "IAID/DUID"); - else { - uint32_t iaid = be32toh(client_id->ns.iaid); - /* TODO: check and stringify DUID */ - r = asprintf(&t, "IAID:0x%x/DUID", iaid); - } - break; - } - if (r < 0) - return -ENOMEM; - - *ret = TAKE_PTR(t); - return 0; -} - int dhcp_client_set_state_callback( sd_dhcp_client *client, sd_dhcp_client_callback_t cb, @@ -360,34 +280,14 @@ int sd_dhcp_client_set_mac( return 0; } -int sd_dhcp_client_get_client_id( - sd_dhcp_client *client, - uint8_t *ret_type, - const uint8_t **ret_data, - size_t *ret_data_len) { - +int sd_dhcp_client_get_client_id(sd_dhcp_client *client, const sd_dhcp_client_id **ret) { assert_return(client, -EINVAL); + assert_return(ret, -EINVAL); - if (client->client_id_len > 0) { - if (client->client_id_len <= offsetof(sd_dhcp_client_id, raw.data)) - return -EINVAL; - - if (ret_type) - *ret_type = client->client_id.type; - if (ret_data) - *ret_data = client->client_id.raw.data; - if (ret_data_len) - *ret_data_len = client->client_id_len - offsetof(sd_dhcp_client_id, raw.data); - return 1; - } - - if (ret_type) - *ret_type = 0; - if (ret_data) - *ret_data = NULL; - if (ret_data_len) - *ret_data_len = 0; + if (!sd_dhcp_client_id_is_set(&client->client_id)) + return -ENODATA; + *ret = &client->client_id; return 0; } @@ -400,7 +300,7 @@ int sd_dhcp_client_set_client_id( assert_return(client, -EINVAL); assert_return(!sd_dhcp_client_is_running(client), -EBUSY); assert_return(data, -EINVAL); - assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL); + assert_return(client_id_data_size_is_valid(data_len), -EINVAL); /* For hardware types, log debug message about unexpected data length. * @@ -413,42 +313,7 @@ int sd_dhcp_client_set_client_id( "Changing client ID to hardware type %u with unexpected address length %zu", type, data_len); - client->client_id.type = type; - memcpy(&client->client_id.raw.data, data, data_len); - client->client_id_len = data_len + sizeof (client->client_id.type); - - return 0; -} - -/** - * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid - * without further modification. Otherwise, if duid_type is supported, DUID - * is set based on that type. Otherwise, an error is returned. - */ -static int dhcp_client_set_iaid( - sd_dhcp_client *client, - bool iaid_set, - uint32_t iaid) { - - int r; - - assert_return(client, -EINVAL); - assert_return(!sd_dhcp_client_is_running(client), -EBUSY); - - zero(client->client_id); - client->client_id.type = 255; - - if (iaid_set) - client->client_id.ns.iaid = htobe32(iaid); - else { - r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr, - /* legacy_unstable_byteorder = */ true, - &client->client_id.ns.iaid); - if (r < 0) - return log_dhcp_client_errno(client, r, "Failed to set IAID: %m"); - } - - return 0; + return sd_dhcp_client_id_set(&client->client_id, type, data, data_len); } static int dhcp_client_set_iaid_duid( @@ -459,18 +324,17 @@ static int dhcp_client_set_iaid_duid( int r; - assert_return(client, -EINVAL); - assert_return(!sd_dhcp_client_is_running(client), -EBUSY); - assert_return(duid, -EINVAL); - assert_return(sd_dhcp_duid_is_set(duid), -ESTALE); + if (!iaid_set) { + r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr, + /* legacy_unstable_byteorder = */ true, + &iaid); + if (r < 0) + return r; - r = dhcp_client_set_iaid(client, iaid_set, iaid); - if (r < 0) - return r; + iaid = be32toh(iaid); + } - memcpy(&client->client_id.ns.duid, &duid->duid, duid->size); - client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid->size; - return 0; + return sd_dhcp_client_id_set_iaid_duid(&client->client_id, iaid, duid); } int sd_dhcp_client_set_iaid_duid_llt( @@ -913,8 +777,8 @@ static int client_message_init( Identifier option is not set */ r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0, SD_DHCP_OPTION_CLIENT_IDENTIFIER, - client->client_id_len, - &client->client_id); + client->client_id.size, + client->client_id.raw); if (r < 0) return r; @@ -1571,10 +1435,8 @@ static int client_parse_message( if (r < 0) return r; - if (client->client_id_len > 0) { - r = dhcp_lease_set_client_id(lease, - (uint8_t *) &client->client_id, - client->client_id_len); + if (sd_dhcp_client_id_is_set(&client->client_id)) { + r = dhcp_lease_set_client_id(lease, &client->client_id); if (r < 0) return r; } @@ -2271,7 +2133,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) { return r; /* If no client identifier exists, construct an RFC 4361-compliant one */ - if (client->client_id_len == 0) { + if (!sd_dhcp_client_id_is_set(&client->client_id)) { r = sd_dhcp_client_set_iaid_duid_en(client, /* iaid_set = */ false, /* iaid = */ 0); if (r < 0) return r; diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 4e3be98a33..fd32fbb049 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -420,7 +420,6 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { free(lease->static_routes); free(lease->classless_routes); - free(lease->client_id); free(lease->vendor_specific); strv_free(lease->search_domains); free(lease->sixrd_br_addresses); @@ -1066,8 +1065,8 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { _cleanup_fclose_ FILE *f = NULL; struct in_addr address; const struct in_addr *addresses; - const void *client_id, *data; - size_t client_id_len, data_len; + const void *data; + size_t data_len; const char *string; uint16_t mtu; _cleanup_free_ sd_dhcp_route **routes = NULL; @@ -1183,11 +1182,10 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { if (r >= 0) fprintf(f, "TIMEZONE=%s\n", string); - r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len); - if (r >= 0) { + if (sd_dhcp_client_id_is_set(&lease->client_id)) { _cleanup_free_ char *client_id_hex = NULL; - client_id_hex = hexmem(client_id, client_id_len); + client_id_hex = hexmem(lease->client_id.raw, lease->client_id.size); if (!client_id_hex) return -ENOMEM; fprintf(f, "CLIENTID=%s\n", client_id_hex); @@ -1478,9 +1476,16 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { } if (client_id_hex) { - r = unhexmem(client_id_hex, SIZE_MAX, &lease->client_id, &lease->client_id_len); + _cleanup_free_ void *data = NULL; + size_t data_size; + + r = unhexmem(client_id_hex, SIZE_MAX, &data, &data_size); if (r < 0) log_debug_errno(r, "Failed to parse client ID %s, ignoring: %m", client_id_hex); + + r = sd_dhcp_client_id_set_raw(&lease->client_id, data, data_size); + if (r < 0) + log_debug_errno(r, "Failed to assign client ID, ignoring: %m"); } if (vendor_specific_hex) { @@ -1537,36 +1542,25 @@ int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { return 0; } -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len) { +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const sd_dhcp_client_id **ret) { assert_return(lease, -EINVAL); - assert_return(client_id, -EINVAL); - assert_return(client_id_len, -EINVAL); + assert_return(ret, -EINVAL); - if (!lease->client_id) + if (!sd_dhcp_client_id_is_set(&lease->client_id)) return -ENODATA; - *client_id = lease->client_id; - *client_id_len = lease->client_id_len; + *ret = &lease->client_id; return 0; } -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len) { +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const sd_dhcp_client_id *client_id) { assert_return(lease, -EINVAL); - assert_return(client_id || client_id_len <= 0, -EINVAL); - if (client_id_len <= 0) - lease->client_id = mfree(lease->client_id); - else { - void *p; + if (!sd_dhcp_client_id_is_set(client_id)) + return sd_dhcp_client_id_clear(&lease->client_id); - p = memdup(client_id, client_id_len); - if (!p) - return -ENOMEM; - - free_and_replace(lease->client_id, p); - lease->client_id_len = client_id_len; - } + lease->client_id = *client_id; return 0; } diff --git a/src/network/networkctl.c b/src/network/networkctl.c index a280bfbf8e..8e677cc010 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -1458,7 +1458,7 @@ static int dump_dhcp_leases(Table *table, const char *prefix, sd_bus *bus, const if (r < 0) return bus_log_parse_error(r); - r = sd_dhcp_client_id_to_string(client_id, client_id_sz, &id); + r = sd_dhcp_client_id_to_string_from_raw(client_id, client_id_sz, &id); if (r < 0) return bus_log_parse_error(r); @@ -2271,8 +2271,7 @@ static int link_status_one( } if (lease) { - const void *client_id; - size_t client_id_len; + const sd_dhcp_client_id *client_id; const char *tz; r = sd_dhcp_lease_get_timezone(lease, &tz); @@ -2284,11 +2283,11 @@ static int link_status_one( return table_log_add_error(r); } - r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len); + r = sd_dhcp_lease_get_client_id(lease, &client_id); if (r >= 0) { _cleanup_free_ char *id = NULL; - r = sd_dhcp_client_id_to_string(client_id, client_id_len, &id); + r = sd_dhcp_client_id_to_string(client_id, &id); if (r >= 0) { r = table_add_many(table, TABLE_FIELD, "DHCP4 Client ID", diff --git a/src/systemd/meson.build b/src/systemd/meson.build index 76531dd12a..7cf30b652b 100644 --- a/src/systemd/meson.build +++ b/src/systemd/meson.build @@ -20,6 +20,7 @@ _systemd_headers = [ systemd_headers = files(_systemd_headers) _not_installed_headers = [ + 'sd-dhcp-client-id.h', 'sd-dhcp-client.h', 'sd-dhcp-duid.h', 'sd-dhcp-lease.h', diff --git a/src/systemd/sd-dhcp-client-id.h b/src/systemd/sd-dhcp-client-id.h new file mode 100644 index 0000000000..c128efc84d --- /dev/null +++ b/src/systemd/sd-dhcp-client-id.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosddhcpclientidhfoo +#define foosddhcpclientidhfoo + +/*** + Copyright © 2013 Intel Corporation. All rights reserved. + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "sd-dhcp-duid.h" + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +typedef struct sd_dhcp_client_id sd_dhcp_client_id; + +int sd_dhcp_client_id_new(sd_dhcp_client_id **ret); +sd_dhcp_client_id* sd_dhcp_client_id_free(sd_dhcp_client_id *client_id); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client_id, sd_dhcp_client_id_free); + +int sd_dhcp_client_id_clear(sd_dhcp_client_id *client_id); + +int sd_dhcp_client_id_is_set(const sd_dhcp_client_id *client_id); + +int sd_dhcp_client_id_get(const sd_dhcp_client_id *client_id, uint8_t *ret_type, const void **ret_data, size_t *ret_size); +int sd_dhcp_client_id_get_raw(const sd_dhcp_client_id *client_id, const void **ret_data, size_t *ret_size); + +int sd_dhcp_client_id_set( + sd_dhcp_client_id *client_id, + uint8_t type, + const void *data, + size_t data_size); +int sd_dhcp_client_id_set_raw( + sd_dhcp_client_id *client_id, + const void *data, + size_t data_size); +int sd_dhcp_client_id_set_iaid_duid( + sd_dhcp_client_id *client_id, + uint32_t iaid, + sd_dhcp_duid *duid); + +int sd_dhcp_client_id_to_string(const sd_dhcp_client_id *client_id, char **ret); +int sd_dhcp_client_id_to_string_from_raw(const void *data, size_t data_size, char **ret); + +_SD_END_DECLARATIONS; + +#endif diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 3a8abc82ed..dcbd79e6b4 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -26,6 +26,7 @@ #include #include "sd-device.h" +#include "sd-dhcp-client-id.h" #include "sd-dhcp-lease.h" #include "sd-dhcp-option.h" #include "sd-event.h" @@ -75,6 +76,9 @@ int sd_dhcp_client_set_mac( const uint8_t *bcast_addr, size_t addr_len, uint16_t arp_type); +int sd_dhcp_client_get_client_id( + sd_dhcp_client *client, + const sd_dhcp_client_id **ret); int sd_dhcp_client_set_client_id( sd_dhcp_client *client, uint8_t type, @@ -107,11 +111,6 @@ __extension__ int sd_dhcp_client_set_iaid_duid_raw( __extension__ int sd_dhcp_client_set_rapid_commit( sd_dhcp_client *client, bool rapid_commit); -int sd_dhcp_client_get_client_id( - sd_dhcp_client *client, - uint8_t *ret_type, - const uint8_t **ret_data, - size_t *ret_data_len); int sd_dhcp_client_set_mtu( sd_dhcp_client *client, uint32_t mtu); @@ -165,8 +164,6 @@ 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, diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index 1ef53ccf1e..95b0dfef22 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -24,6 +24,8 @@ #include #include +#include "sd-dhcp-client-id.h" + #include "_sd-common.h" _SD_BEGIN_DECLARATIONS; @@ -76,7 +78,7 @@ int sd_dhcp_lease_get_captive_portal(sd_dhcp_lease *lease, const char **captive_ int sd_dhcp_lease_get_static_routes(sd_dhcp_lease *lease, sd_dhcp_route ***ret); int sd_dhcp_lease_get_classless_routes(sd_dhcp_lease *lease, sd_dhcp_route ***ret); int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len); -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len); +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const sd_dhcp_client_id **ret); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone); int sd_dhcp_lease_get_6rd( sd_dhcp_lease *lease,