From c5bcbb4c85b35aea1e1647a56e434ede4f21218b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 1 Apr 2026 23:32:41 +0900 Subject: [PATCH 1/6] network: drop unmet conditions Now sd_dhcp_lease object always wraps sd_dhcp_message object, hence we can unconditionally use it. --- src/network/networkd-json.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 35c32a0d18..dcf74d4b8b 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -6,7 +6,7 @@ #include "sd-dhcp-client.h" #include "sd-dhcp6-client.h" -#include "dhcp-lease-internal.h" +#include "dhcp-lease-internal.h" /* IWYU pragma: keep */ #include "dhcp-server-lease-internal.h" #include "dhcp6-lease-internal.h" #include "extract-word.h" @@ -1354,11 +1354,9 @@ static int dhcp_client_lease_append_json(Link *link, sd_json_variant **v) { return r; _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - if (link->dhcp_lease->message) { - r = dhcp_message_build_json(link->dhcp_lease->message, &m); - if (r < 0) - return r; - } + r = dhcp_message_build_json(link->dhcp_lease->message, &m); + if (r < 0) + return r; r = sd_json_buildo( &w, @@ -1428,19 +1426,6 @@ static int dhcp_client_private_options_append_json(Link *link, sd_json_variant * if (!link->dhcp_lease) return 0; - if (!link->dhcp_lease->message) { - LIST_FOREACH(options, option, link->dhcp_lease->private_options) { - r = sd_json_variant_append_arraybo( - &array, - SD_JSON_BUILD_PAIR_UNSIGNED("Option", option->tag), - SD_JSON_BUILD_PAIR_HEX("PrivateOptionData", option->data, option->length)); - if (r < 0) - return r; - } - - return json_variant_set_field_non_null(v, "PrivateOptions", array); - } - for (uint8_t i = SD_DHCP_OPTION_PRIVATE_BASE; i <= SD_DHCP_OPTION_PRIVATE_LAST; i++) { _cleanup_(iovec_done) struct iovec iov = {}; r = dhcp_message_get_option_alloc(link->dhcp_lease->message, i, &iov); From 7f2c6185fe0244b3ae49e5dfee09d94b282971c3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 1 Apr 2026 23:34:19 +0900 Subject: [PATCH 2/6] networkctl: always use DHCP message serialized in JSON desciption Now the interface description by networkd always contains DHCP message (of course when there is a bound DHCP lease). Let's use it. --- src/network/networkctl-dump-util.c | 5 ----- src/network/networkctl-dump-util.h | 2 +- src/network/networkctl-status-link.c | 21 +-------------------- src/network/networkctl-status-system.c | 2 +- 4 files changed, 3 insertions(+), 27 deletions(-) diff --git a/src/network/networkctl-dump-util.c b/src/network/networkctl-dump-util.c index 15fdb103b6..e6fbc45d9a 100644 --- a/src/network/networkctl-dump-util.c +++ b/src/network/networkctl-dump-util.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "sd-dhcp-lease.h" #include "sd-hwdb.h" #include "sd-netlink.h" @@ -212,7 +211,6 @@ int dump_gateways(sd_netlink *rtnl, sd_hwdb *hwdb, Table *table, int ifindex) { int dump_addresses( sd_netlink *rtnl, sd_dhcp_message *message, - sd_dhcp_lease *lease, Table *table, int ifindex) { @@ -233,9 +231,6 @@ int dump_addresses( if (dhcp_message_get_option_address(message, SD_DHCP_OPTION_SERVER_IDENTIFIER, &server_address) < 0) /* The message should be BOOTP, let's fallback to the siaddr field. */ server_address.s_addr = message->header.siaddr; - } else if (lease) { - (void) sd_dhcp_lease_get_address(lease, &dhcp4_address); - (void) sd_dhcp_lease_get_server_identifier(lease, &server_address); } FOREACH_ARRAY(local, local_addrs, n) { diff --git a/src/network/networkctl-dump-util.h b/src/network/networkctl-dump-util.h index 2aafaae475..a4c02f0390 100644 --- a/src/network/networkctl-dump-util.h +++ b/src/network/networkctl-dump-util.h @@ -8,4 +8,4 @@ int dump_list(Table *table, const char *key, char * const *l); int ieee_oui(sd_hwdb *hwdb, const struct ether_addr *mac, char **ret); int dump_gateways(sd_netlink *rtnl, sd_hwdb *hwdb, Table *table, int ifindex); -int dump_addresses(sd_netlink *rtnl, sd_dhcp_message *message, sd_dhcp_lease *lease, Table *table, int ifindex); +int dump_addresses(sd_netlink *rtnl, sd_dhcp_message *message, Table *table, int ifindex); diff --git a/src/network/networkctl-status-link.c b/src/network/networkctl-status-link.c index 9543953df4..dc765a74f1 100644 --- a/src/network/networkctl-status-link.c +++ b/src/network/networkctl-status-link.c @@ -2,7 +2,6 @@ #include "sd-device.h" #include "sd-dhcp-client-id.h" -#include "sd-dhcp-lease.h" #include "sd-dhcp-protocol.h" #include "sd-hwdb.h" #include "sd-netlink.h" @@ -24,7 +23,6 @@ #include "json-util.h" #include "macvlan-util.h" #include "netif-util.h" -#include "network-internal.h" #include "networkctl.h" #include "networkctl-description.h" #include "networkctl-dump-util.h" @@ -242,7 +240,6 @@ static int link_status_one( const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL, *on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup, *on_color_online; _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL; - _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL; _cleanup_(table_unrefp) Table *table = NULL; int r; @@ -294,11 +291,6 @@ static int link_status_one( if (r == -ENOMEM) return log_oom(); - char lease_file[STRLEN("/run/systemd/netif/leases/") + DECIMAL_STR_MAX(int)]; - xsprintf(lease_file, "/run/systemd/netif/leases/%i", info->ifindex); - - (void) dhcp_lease_load(&lease, lease_file); - r = format_config_files(&network_dropins, network); if (r < 0) return r; @@ -780,7 +772,7 @@ static int link_status_one( return r; } - r = dump_addresses(rtnl, info->dhcp_message, lease, table, info->ifindex); + r = dump_addresses(rtnl, info->dhcp_message, table, info->ifindex); if (r < 0) return r; @@ -849,17 +841,6 @@ static int link_status_one( if (r < 0) return table_log_add_error(r); } - } else if (lease) { - const char *tz; - - r = sd_dhcp_lease_get_timezone(lease, &tz); - if (r >= 0) { - r = table_add_many(table, - TABLE_FIELD, "Time Zone", - TABLE_STRING, tz); - if (r < 0) - return table_log_add_error(r); - } } if (sd_dhcp_client_id_is_set(&info->dhcp_client_id)) { diff --git a/src/network/networkctl-status-system.c b/src/network/networkctl-status-system.c index 78dd77819d..35de930423 100644 --- a/src/network/networkctl-status-system.c +++ b/src/network/networkctl-status-system.c @@ -94,7 +94,7 @@ int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) { if (r < 0) return table_log_add_error(r); - r = dump_addresses(rtnl, /* message= */ NULL, /* lease= */ NULL, table, /* ifindex= */ 0); + r = dump_addresses(rtnl, /* message= */ NULL, table, /* ifindex= */ 0); if (r < 0) return r; From ad350e6ecf2061711e5c17b7c0391b872ad0a4e7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 1 Apr 2026 23:36:30 +0900 Subject: [PATCH 3/6] network: drop serialization of DHCP lease No one use it now anymore. Let's drop it. --- src/network/networkd-link.c | 7 +------ src/network/networkd-link.h | 1 - src/network/networkd-state-file.c | 9 --------- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index dcd081039b..3327553836 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -288,7 +288,6 @@ static Link* link_free(Link *link) { free(link->previous_ssid); free(link->driver); - unlink_and_free(link->lease_file); unlink_and_free(link->state_file); sd_device_unref(link->dev); @@ -2713,7 +2712,7 @@ static Link *link_drop_or_unref(Link *link) { DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref); static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { - _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL; + _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL; _cleanup_(link_drop_or_unrefp) Link *link = NULL; unsigned short iftype; int r, ifindex; @@ -2751,9 +2750,6 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { /* Do not update state files when running in test mode. */ if (asprintf(&state_file, "/run/systemd/netif/links/%d", ifindex) < 0) return log_oom_debug(); - - if (asprintf(&lease_file, "/run/systemd/netif/leases/%d", ifindex) < 0) - return log_oom_debug(); } link = new(Link, 1); @@ -2775,7 +2771,6 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID, .state_file = TAKE_PTR(state_file), - .lease_file = TAKE_PTR(lease_file), .n_dns = UINT_MAX, .dns_default_route = -1, diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 33c2fd35a5..456ec99185 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -117,7 +117,6 @@ typedef struct Link { sd_dhcp_client *dhcp_client; sd_dhcp_lease *dhcp_lease; - char *lease_file; unsigned dhcp4_messages; bool dhcp4_configured; char *dhcp4_6rd_tunnel_name; diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c index 7943314b06..3c505f39e6 100644 --- a/src/network/networkd-state-file.c +++ b/src/network/networkd-state-file.c @@ -959,15 +959,6 @@ static int link_save(Link *link) { print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links); print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links); - if (link->dhcp_lease) { - r = dhcp_lease_save(link->dhcp_lease, link->lease_file); - if (r < 0) - return r; - - fprintf(f, "DHCP_LEASE=%s\n", link->lease_file); - } else - (void) unlink(link->lease_file); - r = link_serialize_dhcp6_client(link, f); if (r < 0) return r; From c63c262875f44295b5cf3056f33456fd07947ded Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 1 Apr 2026 23:40:16 +0900 Subject: [PATCH 4/6] sd-dhcp-lease: drop unused dhcp_lease_save() and dhcp_lease_load() They are not used anymore. Let's kill them. --- src/libsystemd-network/network-internal.c | 113 ----- src/libsystemd-network/network-internal.h | 13 - src/libsystemd-network/sd-dhcp-lease.c | 481 ---------------------- src/network/test-network.c | 48 --- 4 files changed, 655 deletions(-) diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index cc29d9fd1b..e32b145370 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -1,18 +1,14 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include #include "sd-dhcp-lease.h" #include "alloc-util.h" -#include "dhcp-route.h" #include "dns-resolver-internal.h" #include "extract-word.h" -#include "hexdecoct.h" #include "in-addr-util.h" #include "network-internal.h" -#include "parse-util.h" #include "string-util.h" #include "strv.h" @@ -216,112 +212,3 @@ int deserialize_dnr(sd_dns_resolver **ret, const char *string) { *ret = TAKE_PTR(dnr); return n; } - -void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size) { - assert(f); - assert(key); - assert(routes); - assert(size); - - fprintf(f, "%s=", key); - - for (size_t i = 0; i < size; i++) { - struct in_addr dest, gw; - uint8_t length; - - assert_se(sd_dhcp_route_get_destination(routes[i], &dest) >= 0); - assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0); - assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0); - - fprintf(f, "%s,%s%s", - IN4_ADDR_PREFIX_TO_STRING(&dest, length), - IN4_ADDR_TO_STRING(&gw), - i < size - 1 ? " ": ""); - } - - fputs("\n", f); -} - -int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const char *string) { - _cleanup_free_ struct sd_dhcp_route *routes = NULL; - size_t size = 0; - - assert(ret); - assert(ret_size); - assert(string); - - /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */ - for (;;) { - _cleanup_free_ char *word = NULL; - char *tok, *tok_end; - unsigned n; - int r; - - r = extract_first_word(&string, &word, NULL, 0); - if (r < 0) - return r; - if (r == 0) - break; - - struct sd_dhcp_route route = {}; - - tok = word; - - /* get the subnet */ - tok_end = strchr(tok, '/'); - if (!tok_end) - continue; - *tok_end = '\0'; - - r = inet_aton(tok, &route.dst_addr); - if (r == 0) - continue; - - tok = tok_end + 1; - - /* get the prefixlen */ - tok_end = strchr(tok, ','); - if (!tok_end) - continue; - - *tok_end = '\0'; - - r = safe_atou(tok, &n); - if (r < 0 || n > 32) - continue; - - route.dst_prefixlen = (uint8_t) n; - tok = tok_end + 1; - - /* get the gateway */ - r = inet_aton(tok, &route.gw_addr); - if (r == 0) - continue; - - if (!GREEDY_REALLOC(routes, size + 1)) - return -ENOMEM; - - routes[size++] = route; - } - - *ret_size = size; - *ret = TAKE_PTR(routes); - - return 0; -} - -int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size) { - _cleanup_free_ char *hex_buf = NULL; - - assert(f); - assert(key); - assert(data); - - hex_buf = hexmem(data, size); - if (!hex_buf) - return -ENOMEM; - - fprintf(f, "%s=%s\n", key, hex_buf); - - return 0; -} diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 658247e350..773f42c42d 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -16,16 +16,3 @@ int deserialize_in6_addrs(struct in6_addr **ret, const char *string); int serialize_dnr(FILE *f, const sd_dns_resolver *dnr, size_t n_dnr, bool *with_leading_space); int deserialize_dnr(sd_dns_resolver **ret, const char *string); - -/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */ -struct sd_dhcp_route; -struct sd_dhcp_lease; - -void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route **routes, size_t size); -int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const char *string); - -/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */ -int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size); - -int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); -int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 9df1a4818d..d74dbe791e 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -3,7 +3,6 @@ Copyright © 2013 Intel Corporation. All rights reserved. ***/ -#include #include #include "sd-dhcp-lease.h" @@ -16,24 +15,15 @@ #include "dns-def.h" #include "dns-domain.h" #include "dns-resolver-internal.h" -#include "env-file.h" -#include "fd-util.h" -#include "fileio.h" -#include "fs-util.h" -#include "hexdecoct.h" #include "hostname-util.h" #include "in-addr-util.h" #include "ip-util.h" #include "network-common.h" -#include "network-internal.h" -#include "parse-util.h" #include "set.h" #include "sort-util.h" -#include "stdio-util.h" #include "string-util.h" #include "strv.h" #include "time-util.h" -#include "tmpfile-util.h" #include "unaligned.h" void dhcp_lease_set_timestamp(sd_dhcp_lease *lease, const triple_timestamp *timestamp) { @@ -1280,477 +1270,6 @@ int dhcp_lease_new(sd_dhcp_lease **ret) { return 0; } -int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { - _cleanup_(unlink_and_freep) char *temp_path = NULL; - _cleanup_fclose_ FILE *f = NULL; - struct in_addr address; - const struct in_addr *addresses; - const void *data; - size_t data_len; - const char *string; - uint16_t mtu; - _cleanup_free_ sd_dhcp_route **routes = NULL; - char **search_domains; - usec_t t; - int r; - - assert(lease); - assert(lease_file); - - r = fopen_temporary(lease_file, &f, &temp_path); - if (r < 0) - return r; - - (void) fchmod(fileno(f), 0644); - - fprintf(f, - "# This is private data. Do not parse.\n"); - - r = sd_dhcp_lease_get_address(lease, &address); - if (r >= 0) - fprintf(f, "ADDRESS=%s\n", IN4_ADDR_TO_STRING(&address)); - - r = sd_dhcp_lease_get_netmask(lease, &address); - if (r >= 0) - fprintf(f, "NETMASK=%s\n", IN4_ADDR_TO_STRING(&address)); - - r = sd_dhcp_lease_get_router(lease, &addresses); - if (r > 0) { - fputs("ROUTER=", f); - serialize_in_addrs(f, addresses, r, NULL, NULL); - fputc('\n', f); - } - - r = sd_dhcp_lease_get_server_identifier(lease, &address); - if (r >= 0) - fprintf(f, "SERVER_ADDRESS=%s\n", IN4_ADDR_TO_STRING(&address)); - - r = sd_dhcp_lease_get_next_server(lease, &address); - if (r >= 0) - fprintf(f, "NEXT_SERVER=%s\n", IN4_ADDR_TO_STRING(&address)); - - r = sd_dhcp_lease_get_broadcast(lease, &address); - if (r >= 0) - fprintf(f, "BROADCAST=%s\n", IN4_ADDR_TO_STRING(&address)); - - r = sd_dhcp_lease_get_mtu(lease, &mtu); - if (r >= 0) - fprintf(f, "MTU=%" PRIu16 "\n", mtu); - - r = sd_dhcp_lease_get_t1(lease, &t); - if (r >= 0) - fprintf(f, "T1=%s\n", FORMAT_TIMESPAN(t, USEC_PER_SEC)); - - r = sd_dhcp_lease_get_t2(lease, &t); - if (r >= 0) - fprintf(f, "T2=%s\n", FORMAT_TIMESPAN(t, USEC_PER_SEC)); - - r = sd_dhcp_lease_get_lifetime(lease, &t); - if (r >= 0) - fprintf(f, "LIFETIME=%s\n", FORMAT_TIMESPAN(t, USEC_PER_SEC)); - - r = sd_dhcp_lease_get_dns(lease, &addresses); - if (r > 0) { - fputs("DNS=", f); - serialize_in_addrs(f, addresses, r, NULL, NULL); - fputc('\n', f); - } - - sd_dns_resolver *resolvers; - r = sd_dhcp_lease_get_dnr(lease, &resolvers); - if (r > 0) { - fputs("DNR=", f); - serialize_dnr(f, resolvers, r, NULL); - fputc('\n', f); - } - - r = sd_dhcp_lease_get_ntp(lease, &addresses); - if (r > 0) { - fputs("NTP=", f); - serialize_in_addrs(f, addresses, r, NULL, NULL); - fputc('\n', f); - } - - r = sd_dhcp_lease_get_sip(lease, &addresses); - if (r > 0) { - fputs("SIP=", f); - serialize_in_addrs(f, addresses, r, NULL, NULL); - fputc('\n', f); - } - - r = sd_dhcp_lease_get_domainname(lease, &string); - if (r >= 0) - fprintf(f, "DOMAINNAME=%s\n", string); - - r = sd_dhcp_lease_get_search_domains(lease, &search_domains); - if (r > 0) { - fputs("DOMAIN_SEARCH_LIST=", f); - fputstrv(f, search_domains, NULL, NULL); - fputc('\n', f); - } - - r = sd_dhcp_lease_get_hostname(lease, &string); - if (r >= 0) - fprintf(f, "HOSTNAME=%s\n", string); - - r = sd_dhcp_lease_get_root_path(lease, &string); - if (r >= 0) - fprintf(f, "ROOT_PATH=%s\n", string); - - r = sd_dhcp_lease_get_static_routes(lease, &routes); - if (r > 0) - serialize_dhcp_routes(f, "STATIC_ROUTES", routes, r); - - routes = mfree(routes); - r = sd_dhcp_lease_get_classless_routes(lease, &routes); - if (r > 0) - serialize_dhcp_routes(f, "CLASSLESS_ROUTES", routes, r); - - r = sd_dhcp_lease_get_timezone(lease, &string); - if (r >= 0) - fprintf(f, "TIMEZONE=%s\n", string); - - if (sd_dhcp_client_id_is_set(&lease->client_id)) { - _cleanup_free_ char *client_id_hex = NULL; - - 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); - } - - r = sd_dhcp_lease_get_vendor_specific(lease, &data, &data_len); - if (r >= 0) { - _cleanup_free_ char *option_hex = NULL; - - option_hex = hexmem(data, data_len); - if (!option_hex) - return -ENOMEM; - fprintf(f, "VENDOR_SPECIFIC=%s\n", option_hex); - } - - LIST_FOREACH(options, option, lease->private_options) { - char key[STRLEN("OPTION_000")+1]; - - xsprintf(key, "OPTION_%" PRIu8, option->tag); - r = serialize_dhcp_option(f, key, option->data, option->length); - if (r < 0) - return r; - } - - r = fflush_and_check(f); - if (r < 0) - return r; - - r = conservative_rename(temp_path, lease_file); - if (r < 0) - return r; - - temp_path = mfree(temp_path); - - return 0; -} - -static char **private_options_free(char **options) { - if (!options) - return NULL; - - free_many_charp(options, SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1); - - return mfree(options); -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(char**, private_options_free); - -int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { - _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL; - _cleanup_free_ char - *address = NULL, - *router = NULL, - *netmask = NULL, - *server_address = NULL, - *next_server = NULL, - *broadcast = NULL, - *dns = NULL, - *dnr = NULL, - *ntp = NULL, - *sip = NULL, - *pop3 = NULL, - *smtp = NULL, - *lpr = NULL, - *mtu = NULL, - *static_routes = NULL, - *classless_routes = NULL, - *domains = NULL, - *client_id_hex = NULL, - *vendor_specific_hex = NULL, - *lifetime = NULL, - *t1 = NULL, - *t2 = NULL; - _cleanup_(private_options_freep) char **options = NULL; - - int r, i; - - assert(lease_file); - assert(ret); - - r = dhcp_lease_new(&lease); - if (r < 0) - return r; - - options = new0(char*, SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1); - if (!options) - return -ENOMEM; - - r = parse_env_file(NULL, lease_file, - "ADDRESS", &address, - "ROUTER", &router, - "NETMASK", &netmask, - "SERVER_ADDRESS", &server_address, - "NEXT_SERVER", &next_server, - "BROADCAST", &broadcast, - "DNS", &dns, - "DNR", &dnr, - "NTP", &ntp, - "SIP", &sip, - "POP3", &pop3, - "SMTP", &smtp, - "LPR", &lpr, - "MTU", &mtu, - "DOMAINNAME", &lease->domainname, - "HOSTNAME", &lease->hostname, - "DOMAIN_SEARCH_LIST", &domains, - "ROOT_PATH", &lease->root_path, - "STATIC_ROUTES", &static_routes, - "CLASSLESS_ROUTES", &classless_routes, - "CLIENTID", &client_id_hex, - "TIMEZONE", &lease->timezone, - "VENDOR_SPECIFIC", &vendor_specific_hex, - "LIFETIME", &lifetime, - "T1", &t1, - "T2", &t2, - "OPTION_224", &options[0], - "OPTION_225", &options[1], - "OPTION_226", &options[2], - "OPTION_227", &options[3], - "OPTION_228", &options[4], - "OPTION_229", &options[5], - "OPTION_230", &options[6], - "OPTION_231", &options[7], - "OPTION_232", &options[8], - "OPTION_233", &options[9], - "OPTION_234", &options[10], - "OPTION_235", &options[11], - "OPTION_236", &options[12], - "OPTION_237", &options[13], - "OPTION_238", &options[14], - "OPTION_239", &options[15], - "OPTION_240", &options[16], - "OPTION_241", &options[17], - "OPTION_242", &options[18], - "OPTION_243", &options[19], - "OPTION_244", &options[20], - "OPTION_245", &options[21], - "OPTION_246", &options[22], - "OPTION_247", &options[23], - "OPTION_248", &options[24], - "OPTION_249", &options[25], - "OPTION_250", &options[26], - "OPTION_251", &options[27], - "OPTION_252", &options[28], - "OPTION_253", &options[29], - "OPTION_254", &options[30]); - if (r < 0) - return r; - - if (address) { - r = inet_pton(AF_INET, address, &lease->address); - if (r <= 0) - log_debug("Failed to parse address %s, ignoring.", address); - } - - if (router) { - r = deserialize_in_addrs(&lease->router, router); - if (r < 0) - log_debug_errno(r, "Failed to deserialize router addresses %s, ignoring: %m", router); - else - lease->router_size = r; - } - - if (netmask) { - r = inet_pton(AF_INET, netmask, &lease->subnet_mask); - if (r <= 0) - log_debug("Failed to parse netmask %s, ignoring.", netmask); - } - - if (server_address) { - r = inet_pton(AF_INET, server_address, &lease->server_address); - if (r <= 0) - log_debug("Failed to parse server address %s, ignoring.", server_address); - } - - if (next_server) { - r = inet_pton(AF_INET, next_server, &lease->next_server); - if (r <= 0) - log_debug("Failed to parse next server %s, ignoring.", next_server); - } - - if (broadcast) { - r = inet_pton(AF_INET, broadcast, &lease->broadcast); - if (r <= 0) - log_debug("Failed to parse broadcast address %s, ignoring.", broadcast); - } - - if (dns) { - r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_DNS].addr, dns); - if (r < 0) - log_debug_errno(r, "Failed to deserialize DNS servers %s, ignoring: %m", dns); - else - lease->servers[SD_DHCP_LEASE_DNS].size = r; - } - - if (dnr) { - r = deserialize_dnr(&lease->dnr, dnr); - if (r < 0) - log_debug_errno(r, "Failed to deserialize DNR servers %s, ignoring: %m", dnr); - else - lease->n_dnr = r; - } - - if (ntp) { - r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_NTP].addr, ntp); - if (r < 0) - log_debug_errno(r, "Failed to deserialize NTP servers %s, ignoring: %m", ntp); - else - lease->servers[SD_DHCP_LEASE_NTP].size = r; - } - - if (sip) { - r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_SIP].addr, sip); - if (r < 0) - log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip); - else - lease->servers[SD_DHCP_LEASE_SIP].size = r; - } - - if (pop3) { - r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_POP3].addr, pop3); - if (r < 0) - log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3); - else - lease->servers[SD_DHCP_LEASE_POP3].size = r; - } - - if (smtp) { - r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_SMTP].addr, smtp); - if (r < 0) - log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp); - else - lease->servers[SD_DHCP_LEASE_SMTP].size = r; - } - - if (lpr) { - r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_LPR].addr, lpr); - if (r < 0) - log_debug_errno(r, "Failed to deserialize LPR server %s, ignoring: %m", lpr); - else - lease->servers[SD_DHCP_LEASE_LPR].size = r; - } - - if (mtu) { - r = safe_atou16(mtu, &lease->mtu); - if (r < 0) - log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu); - } - - if (domains) { - _cleanup_strv_free_ char **a = NULL; - a = strv_split(domains, " "); - if (!a) - return -ENOMEM; - - if (!strv_isempty(a)) - lease->search_domains = TAKE_PTR(a); - } - - if (static_routes) { - r = deserialize_dhcp_routes( - &lease->static_routes, - &lease->n_static_routes, - static_routes); - if (r < 0) - log_debug_errno(r, "Failed to parse DHCP static routes %s, ignoring: %m", static_routes); - } - - if (classless_routes) { - r = deserialize_dhcp_routes( - &lease->classless_routes, - &lease->n_classless_routes, - classless_routes); - if (r < 0) - log_debug_errno(r, "Failed to parse DHCP classless routes %s, ignoring: %m", classless_routes); - } - - if (lifetime) { - r = parse_sec(lifetime, &lease->lifetime); - if (r < 0) - log_debug_errno(r, "Failed to parse lifetime %s, ignoring: %m", lifetime); - } - - if (t1) { - r = parse_sec(t1, &lease->t1); - if (r < 0) - log_debug_errno(r, "Failed to parse T1 %s, ignoring: %m", t1); - } - - if (t2) { - r = parse_sec(t2, &lease->t2); - if (r < 0) - log_debug_errno(r, "Failed to parse T2 %s, ignoring: %m", t2); - } - - if (client_id_hex) { - _cleanup_free_ void *data = NULL; - size_t data_size; - - r = unhexmem(client_id_hex, &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) { - r = unhexmem(vendor_specific_hex, &lease->vendor_specific, &lease->vendor_specific_len); - if (r < 0) - log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex); - } - - for (i = 0; i <= SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE; i++) { - _cleanup_free_ void *data = NULL; - size_t len; - - if (!options[i]) - continue; - - r = unhexmem(options[i], &data, &len); - if (r < 0) { - log_debug_errno(r, "Failed to parse private DHCP option %s, ignoring: %m", options[i]); - continue; - } - - r = dhcp_lease_insert_private_option(lease, SD_DHCP_OPTION_PRIVATE_BASE + i, data, len); - if (r < 0) - return r; - } - - *ret = TAKE_PTR(lease); - - return 0; -} - int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { struct in_addr address, mask; int r; diff --git a/src/network/test-network.c b/src/network/test-network.c index c78c50e3a7..ee0e5d13b5 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -1,9 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include - #include "alloc-util.h" -#include "dhcp-route.h" #include "hashmap.h" #include "hostname-setup.h" #include "network-internal.h" @@ -42,51 +39,6 @@ TEST(deserialize_in_addr) { ASSERT_TRUE(in6_addr_equal(&f.in6, &addresses6[2])); } -TEST(deserialize_dhcp_routes) { - _cleanup_free_ struct sd_dhcp_route *routes = NULL; - size_t size; - - ASSERT_OK(deserialize_dhcp_routes(&routes, &size, "")); - ASSERT_EQ(size, 0U); - ASSERT_NULL(routes); - - ASSERT_OK(deserialize_dhcp_routes(&routes, &size, "192.168.0.0/16,192.168.0.1 10.1.2.0/24,10.1.2.1 0.0.0.0/0,10.0.1.1")); - ASSERT_EQ(size, 3U); - ASSERT_NOT_NULL(routes); - - ASSERT_EQ(routes[0].dst_addr.s_addr, inet_addr("192.168.0.0")); - ASSERT_EQ(routes[0].gw_addr.s_addr, inet_addr("192.168.0.1")); - ASSERT_EQ(routes[0].dst_prefixlen, 16U); - - ASSERT_EQ(routes[1].dst_addr.s_addr, inet_addr("10.1.2.0")); - ASSERT_EQ(routes[1].gw_addr.s_addr, inet_addr("10.1.2.1")); - ASSERT_EQ(routes[1].dst_prefixlen, 24U); - - ASSERT_EQ(routes[2].dst_addr.s_addr, inet_addr("0.0.0.0")); - ASSERT_EQ(routes[2].gw_addr.s_addr, inet_addr("10.0.1.1")); - ASSERT_EQ(routes[2].dst_prefixlen, 0U); - - routes = mfree(routes); - - ASSERT_OK(deserialize_dhcp_routes(&routes, &size, "192.168.0.0/16,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.1")); - ASSERT_EQ(size, 2U); - ASSERT_NOT_NULL(routes); - - ASSERT_EQ(routes[0].dst_addr.s_addr, inet_addr("192.168.0.0")); - ASSERT_EQ(routes[0].gw_addr.s_addr, inet_addr("192.168.0.1")); - ASSERT_EQ(routes[0].dst_prefixlen, 16U); - - ASSERT_EQ(routes[1].dst_addr.s_addr, inet_addr("0.0.0.0")); - ASSERT_EQ(routes[1].gw_addr.s_addr, inet_addr("10.0.1.1")); - ASSERT_EQ(routes[1].dst_prefixlen, 0U); - - routes = mfree(routes); - - ASSERT_OK(deserialize_dhcp_routes(&routes, &size, "192.168.0.0/55,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.X")); - ASSERT_EQ(size, 0U); - ASSERT_NULL(routes); -} - static void test_route_tables_one(Manager *manager, const char *name, uint32_t number) { _cleanup_free_ char *str = NULL, *expected = NULL, *num_str = NULL; uint32_t t; From 4d1779a7c59f7958b30ab3739ac2475b2ed53567 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 1 Apr 2026 23:44:39 +0900 Subject: [PATCH 5/6] sd-dhcp-lease: drop several more unused functions and conditions --- src/libsystemd-network/dhcp-lease-internal.h | 29 +- src/libsystemd-network/meson.build | 3 - src/libsystemd-network/sd-dhcp-lease.c | 936 +------------------ src/libsystemd-network/test-sd-dhcp-lease.c | 82 -- src/systemd/sd-dhcp-lease.h | 9 +- 5 files changed, 7 insertions(+), 1052 deletions(-) delete mode 100644 src/libsystemd-network/test-sd-dhcp-lease.c diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index b26de88351..c00b8a6cd5 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -11,15 +11,6 @@ #include "dhcp-client-id-internal.h" #include "dhcp-message.h" #include "dhcp-option.h" -#include "list.h" - -struct sd_dhcp_raw_option { - LIST_FIELDS(struct sd_dhcp_raw_option, options); - - uint8_t tag; - uint8_t length; - void *data; -}; struct sd_dhcp_lease { unsigned n_ref; @@ -36,15 +27,12 @@ struct sd_dhcp_lease { /* each 0 if unset */ be32_t address; be32_t server_address; - be32_t next_server; be32_t subnet_mask; be32_t broadcast; struct in_addr *router; size_t router_size; - bool rapid_commit; - DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX]; sd_dns_resolver *dnr; @@ -59,16 +47,9 @@ struct sd_dhcp_lease { char *domainname; char **search_domains; - char *hostname; /* SD_DHCP_OPTION_HOST_NAME (12) */ - char *fqdn; /* SD_DHCP_OPTION_FQDN (81) */ - char *root_path; + char *hostname; char *captive_portal; - sd_dhcp_client_id client_id; - - void *vendor_specific; - size_t vendor_specific_len; - char *timezone; uint8_t sixrd_ipv4masklen; @@ -76,18 +57,10 @@ struct sd_dhcp_lease { struct in6_addr sixrd_prefix; struct in_addr *sixrd_br_addresses; size_t sixrd_n_br_addresses; - - LIST_HEAD(struct sd_dhcp_raw_option, private_options); }; int dhcp_lease_new(sd_dhcp_lease **ret); -int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata); -int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains); -int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len); - 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 sd_dhcp_client_id *client_id); int dhcp_client_parse_message(sd_dhcp_client *client, const struct iovec *iov, sd_dhcp_lease **ret); diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build index 74e09fac84..fed2c98c71 100644 --- a/src/libsystemd-network/meson.build +++ b/src/libsystemd-network/meson.build @@ -122,9 +122,6 @@ executables += [ 'sources' : files('test-ndisc-send.c'), 'type' : 'manual', }, - network_test_template + { - 'sources' : files('test-sd-dhcp-lease.c'), - }, network_test_template + { 'sources' : files('test-tlv-util.c'), }, diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index d74dbe791e..641ee8561b 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -11,20 +11,14 @@ #include "dhcp-client-internal.h" #include "dhcp-lease-internal.h" #include "dhcp-option.h" -#include "dhcp-route.h" -#include "dns-def.h" -#include "dns-domain.h" +#include "dhcp-route.h" /* IWYU pragma: keep */ #include "dns-resolver-internal.h" -#include "hostname-util.h" #include "in-addr-util.h" #include "ip-util.h" -#include "network-common.h" #include "set.h" -#include "sort-util.h" #include "string-util.h" #include "strv.h" #include "time-util.h" -#include "unaligned.h" void dhcp_lease_set_timestamp(sd_dhcp_lease *lease, const triple_timestamp *timestamp) { assert(lease); @@ -168,15 +162,6 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) { return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SIP, addr); } -int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr) { - return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_POP3, addr); -} -int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr) { - return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP, addr); -} -int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr) { - return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_LPR, addr); -} int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { assert_return(lease, -EINVAL); @@ -189,30 +174,14 @@ int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) return 0; } -int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) { +int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **ret) { assert_return(lease, -EINVAL); - assert_return(hostname, -EINVAL); - /* FQDN option (81) always takes precedence. */ - - if (lease->fqdn) - *hostname = lease->fqdn; - else if (lease->hostname) - *hostname = lease->hostname; - else + if (!lease->hostname) return -ENODATA; - return 0; -} - -int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) { - assert_return(lease, -EINVAL); - assert_return(root_path, -EINVAL); - - if (!lease->root_path) - return -ENODATA; - - *root_path = lease->root_path; + if (ret) + *ret = lease->hostname; return 0; } @@ -299,17 +268,6 @@ int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *ad return 0; } -int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) { - assert_return(lease, -EINVAL); - assert_return(addr, -EINVAL); - - if (lease->next_server == 0) - return -ENODATA; - - addr->s_addr = lease->next_server; - return 0; -} - /* * The returned routes array must be freed by the caller. * Route objects have the same lifetime of the lease and must not be freed. @@ -394,36 +352,14 @@ int sd_dhcp_lease_has_6rd(sd_dhcp_lease *lease) { return lease && lease->sixrd_n_br_addresses > 0; } -int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) { - assert_return(lease, -EINVAL); - assert_return(data, -EINVAL); - assert_return(data_len, -EINVAL); - - if (lease->vendor_specific_len <= 0) - return -ENODATA; - - *data = lease->vendor_specific; - *data_len = lease->vendor_specific_len; - return 0; -} - static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { - struct sd_dhcp_raw_option *option; - assert(lease); sd_dhcp_message_unref(lease->message); - while ((option = LIST_POP(options, lease->private_options))) { - free(option->data); - free(option); - } - - free(lease->root_path); free(lease->router); free(lease->timezone); free(lease->hostname); - free(lease->fqdn); free(lease->domainname); free(lease->captive_portal); @@ -433,7 +369,6 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { dns_resolver_free_array(lease->dnr, lease->n_dnr); free(lease->static_routes); free(lease->classless_routes); - free(lease->vendor_specific); strv_free(lease->search_domains); free(lease->sixrd_br_addresses); return mfree(lease); @@ -441,820 +376,6 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_lease, sd_dhcp_lease, dhcp_lease_free); -static int lease_parse_be32_seconds(const uint8_t *option, size_t len, bool max_as_infinity, usec_t *ret) { - assert(option); - assert(ret); - - if (len != 4) - return -EINVAL; - - *ret = unaligned_be32_sec_to_usec(option, max_as_infinity); - return 0; -} - -static int lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) { - assert(option); - assert(ret); - - if (len != 2) - return -EINVAL; - - *ret = unaligned_read_be16((be16_t*) option); - if (*ret < min) - *ret = min; - - return 0; -} - -static int lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) { - assert(option); - assert(ret); - - if (len != 4) - return -EINVAL; - - memcpy(ret, option, 4); - return 0; -} - -static int lease_parse_domain(const uint8_t *option, size_t len, char **domain) { - _cleanup_free_ char *name = NULL, *normalized = NULL; - int r; - - assert(option); - assert(domain); - - r = dhcp_option_parse_string(option, len, &name); - if (r < 0) - return r; - if (!name) { - *domain = mfree(*domain); - return 0; - } - - r = dns_name_normalize(name, 0, &normalized); - if (r < 0) - return r; - - if (is_localhost(normalized)) - return -EINVAL; - - if (dns_name_is_root(normalized)) - return -EINVAL; - - return free_and_replace(*domain, normalized); -} - -static int lease_parse_fqdn(const uint8_t *option, size_t len, char **fqdn) { - _cleanup_free_ char *name = NULL, *normalized = NULL; - int r; - - assert(option); - assert(fqdn); - - /* RFC 4702 Section 2 - * - * Byte 0: Flags (S: server should perform A RR updates, O: override existing A RR, - * E: encoding (0=ASCII, 1=Wire format), N: no server updates) - * Byte 1: RCODE1 (ignored on receipt) - * Byte 2: RCODE2 (ignored on receipt) - * Bytes 3+: Domain Name */ - - if (len <= 3) - return -EBADMSG; - - size_t data_len = len - 3; - const uint8_t *data = option + 3; - - /* In practice, many servers send DNS wire format regardless of the E flag, so ignore and try wire - * format first, then fall back to ASCII if that fails. */ - r = dns_name_from_wire_format(&data, &data_len, &name); - if (r < 0) { - if (FLAGS_SET(option[0], DHCP_FQDN_FLAG_E)) - return -EBADMSG; - - /* Wire format failed, try ASCII format */ - r = dhcp_option_parse_string(option + 3, len - 3, &name); - if (r < 0) - return r; - } - - if (!name) { - *fqdn = mfree(*fqdn); - return 0; - } - - r = dns_name_normalize(name, 0, &normalized); - if (r < 0) - return r; - - if (is_localhost(normalized)) - return -EINVAL; - - if (dns_name_is_root(normalized)) - return -EINVAL; - - return free_and_replace(*fqdn, normalized); -} - -static int lease_parse_captive_portal(const uint8_t *option, size_t len, char **uri) { - _cleanup_free_ char *s = NULL; - int r; - - assert(option); - assert(uri); - - r = dhcp_option_parse_string(option, len, &s); - if (r < 0) - return r; - if (s && !in_charset(s, URI_VALID)) - return -EINVAL; - - return free_and_replace(*uri, s); -} - -static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **addresses, size_t *n_addresses) { - assert(option || len == 0); - assert(addresses); - assert(n_addresses); - - if (len <= 0) { - *n_addresses = 0; - *addresses = mfree(*addresses); - return 0; - } - - if (len % 4 != 0) - return -EINVAL; - - size_t n = len / 4; - struct in_addr *a = newdup(struct in_addr, option, n); - if (!a) - return -ENOMEM; - - *n_addresses = n; - return free_and_replace(*addresses, a); -} - -static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **sips, size_t *n_sips) { - assert(option || len == 0); - assert(sips); - assert(n_sips); - - if (len <= 0) - return -EINVAL; - - /* The SIP record is like the other, regular server records, but prefixed with a single "encoding" - * byte that is either 0 or 1. We only support it to be 1 for now. Let's drop it and parse it like - * the other fields */ - - if (option[0] != 1) { /* We only support IP address encoding for now */ - *sips = mfree(*sips); - *n_sips = 0; - return 0; - } - - return lease_parse_in_addrs(option + 1, len - 1, sips, n_sips); -} - -static int lease_parse_dns_name(const uint8_t *optval, size_t optlen, char **ret) { - _cleanup_free_ char *name = NULL; - int r; - - assert(optval); - assert(ret); - - r = dns_name_from_wire_format(&optval, &optlen, &name); - if (r < 0) - return r; - if (r == 0 || optlen != 0) - return -EBADMSG; - - *ret = TAKE_PTR(name); - return r; -} - -static int lease_parse_dnr(const uint8_t *option, size_t len, sd_dns_resolver **dnr, size_t *n_dnr) { - int r; - sd_dns_resolver *res_list = NULL; - size_t n_resolvers = 0; - CLEANUP_ARRAY(res_list, n_resolvers, dns_resolver_free_array); - - assert(option || len == 0); - assert(dnr); - assert(n_dnr); - - _cleanup_(sd_dns_resolver_done) sd_dns_resolver res = {}; - - size_t offset = 0; - while (offset < len) { - /* Instance Data length */ - if (offset + 2 > len) - return -EBADMSG; - size_t ilen = unaligned_read_be16(option + offset); - if (offset + ilen + 2 > len) - return -EBADMSG; - offset += 2; - size_t iend = offset + ilen; - - /* priority */ - if (offset + 2 > len) - return -EBADMSG; - res.priority = unaligned_read_be16(option + offset); - offset += 2; - - /* Authenticated Domain Name */ - if (offset + 1 > len) - return -EBADMSG; - ilen = option[offset++]; - if (offset + ilen > iend) - return -EBADMSG; - - r = lease_parse_dns_name(option + offset, ilen, &res.auth_name); - if (r < 0) - return r; - r = dns_name_is_valid_ldh(res.auth_name); - if (r < 0) - return r; - if (!r) - return -EBADMSG; - if (dns_name_is_root(res.auth_name)) - return -EBADMSG; - offset += ilen; - - /* RFC9463 § 3.1.6: In ADN-only mode, server omits everything after the ADN. - * We don't support these, but they are not invalid. */ - if (offset == iend) { - log_debug("Received ADN-only DNRv4 option, ignoring."); - sd_dns_resolver_done(&res); - continue; - } - - /* IPv4 addrs */ - if (offset + 1 > len) - return -EBADMSG; - ilen = option[offset++]; - if (offset + ilen > iend) - return -EBADMSG; - - size_t n_addrs; - _cleanup_free_ struct in_addr *addrs = NULL; - r = lease_parse_in_addrs(option + offset, ilen, &addrs, &n_addrs); - if (r < 0) - return r; - offset += ilen; - - /* RFC9463 § 3.1.8: option MUST include at least one valid IP addr */ - if (!n_addrs) - return -EBADMSG; - - res.addrs = new(union in_addr_union, n_addrs); - if (!res.addrs) - return -ENOMEM; - for (size_t i = 0; i < n_addrs; i++) { - union in_addr_union addr = {.in = addrs[i]}; - /* RFC9463 § 5.2 client MUST discard multicast and host loopback addresses */ - if (in_addr_is_multicast(AF_INET, &addr) || - in_addr_is_localhost(AF_INET, &addr)) - return -EBADMSG; - res.addrs[i] = addr; - } - res.n_addrs = n_addrs; - res.family = AF_INET; - - /* service params */ - r = dnr_parse_svc_params(option + offset, iend-offset, &res); - if (r < 0) - return r; - if (r == 0) { - /* We can't use this record, but it was not invalid. */ - log_debug("Received DNRv4 option with unsupported SvcParams, ignoring."); - sd_dns_resolver_done(&res); - continue; - } - offset = iend; - - /* Append the latest resolver */ - if (!GREEDY_REALLOC0(res_list, n_resolvers+1)) - return -ENOMEM; - - res_list[n_resolvers++] = TAKE_STRUCT(res); - } - - typesafe_qsort(res_list, n_resolvers, dns_resolver_prio_compare); - - dns_resolver_free_array(*dnr, *n_dnr); - *dnr = TAKE_PTR(res_list); - *n_dnr = n_resolvers; - - return n_resolvers; -} - -static int lease_parse_static_routes(sd_dhcp_lease *lease, const uint8_t *option, size_t len) { - int r; - - assert(lease); - assert(option || len <= 0); - - if (len % 8 != 0) - return -EINVAL; - - while (len >= 8) { - struct in_addr dst, gw; - uint8_t prefixlen; - - assert_se(lease_parse_be32(option, 4, &dst.s_addr) >= 0); - option += 4; - - assert_se(lease_parse_be32(option, 4, &gw.s_addr) >= 0); - option += 4; - - len -= 8; - - r = in4_addr_default_prefixlen(&dst, &prefixlen); - if (r < 0) { - log_debug("sd-dhcp-lease: cannot determine class of received static route, ignoring."); - continue; - } - - (void) in4_addr_mask(&dst, prefixlen); - - if (!GREEDY_REALLOC(lease->static_routes, lease->n_static_routes + 1)) - return -ENOMEM; - - lease->static_routes[lease->n_static_routes++] = (struct sd_dhcp_route) { - .dst_addr = dst, - .gw_addr = gw, - .dst_prefixlen = prefixlen, - }; - } - - return 0; -} - -/* parses RFC3442 Classless Static Route Option */ -static int lease_parse_classless_routes(sd_dhcp_lease *lease, const uint8_t *option, size_t len) { - assert(lease); - assert(option || len <= 0); - - /* option format: (subnet-mask-width significant-subnet-octets gateway-ip) */ - - while (len > 0) { - uint8_t prefixlen, dst_octets; - struct in_addr dst = {}, gw; - - prefixlen = *option; - option++; - len--; - - dst_octets = DIV_ROUND_UP(prefixlen, 8); - - /* can't have more than 4 octets in IPv4 */ - if (dst_octets > 4 || len < dst_octets) - return -EINVAL; - - memcpy(&dst, option, dst_octets); - option += dst_octets; - len -= dst_octets; - - if (len < 4) - return -EINVAL; - - assert_se(lease_parse_be32(option, 4, &gw.s_addr) >= 0); - option += 4; - len -= 4; - - if (!GREEDY_REALLOC(lease->classless_routes, lease->n_classless_routes + 1)) - return -ENOMEM; - - lease->classless_routes[lease->n_classless_routes++] = (struct sd_dhcp_route) { - .dst_addr = dst, - .gw_addr = gw, - .dst_prefixlen = prefixlen, - }; - } - - return 0; -} - -static int lease_parse_6rd(sd_dhcp_lease *lease, const uint8_t *option, size_t len) { - uint8_t ipv4masklen, prefixlen; - struct in6_addr prefix; - _cleanup_free_ struct in_addr *br_addresses = NULL; - size_t n_br_addresses; - - assert(lease); - assert(option); - - /* See RFC 5969 Section 7.1.1 */ - - if (lease->sixrd_n_br_addresses > 0) - /* Multiple 6rd option?? */ - return -EINVAL; - - /* option-length: The length of the DHCP option in octets (22 octets with one BR IPv4 address). */ - if (len < 2 + sizeof(struct in6_addr) + sizeof(struct in_addr) || - (len - 2 - sizeof(struct in6_addr)) % sizeof(struct in_addr) != 0) - return -EINVAL; - - /* IPv4MaskLen: The number of high-order bits that are identical across all CE IPv4 addresses - * within a given 6rd domain. This may be any value between 0 and 32. Any value - * greater than 32 is invalid. */ - ipv4masklen = option[0]; - if (ipv4masklen > 32) - return -EINVAL; - - /* 6rdPrefixLen: The IPv6 prefix length of the SP's 6rd IPv6 prefix in number of bits. For the - * purpose of bounds checking by DHCP option processing, the sum of - * (32 - IPv4MaskLen) + 6rdPrefixLen MUST be less than or equal to 128. */ - prefixlen = option[1]; - if (32 - ipv4masklen + prefixlen > 128) - return -EINVAL; - - /* 6rdPrefix: The service provider's 6rd IPv6 prefix represented as a 16-octet IPv6 address. - * The bits in the prefix after the 6rdPrefixlen number of bits are reserved and - * MUST be initialized to zero by the sender and ignored by the receiver. */ - memcpy(&prefix, option + 2, sizeof(struct in6_addr)); - (void) in6_addr_mask(&prefix, prefixlen); - - /* 6rdBRIPv4Address: One or more IPv4 addresses of the 6rd Border Relays for a given 6rd domain. */ - n_br_addresses = (len - 2 - sizeof(struct in6_addr)) / sizeof(struct in_addr); - br_addresses = newdup(struct in_addr, option + 2 + sizeof(struct in6_addr), n_br_addresses); - if (!br_addresses) - return -ENOMEM; - - lease->sixrd_ipv4masklen = ipv4masklen; - lease->sixrd_prefixlen = prefixlen; - lease->sixrd_prefix = prefix; - lease->sixrd_br_addresses = TAKE_PTR(br_addresses); - lease->sixrd_n_br_addresses = n_br_addresses; - - return 0; -} - -int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata) { - sd_dhcp_lease *lease = ASSERT_PTR(userdata); - int r; - - switch (code) { - - case SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME: - r = lease_parse_be32_seconds(option, len, /* max_as_infinity= */ true, &lease->lifetime); - if (r < 0) - log_debug_errno(r, "Failed to parse lease time, ignoring: %m"); - - break; - - case SD_DHCP_OPTION_SERVER_IDENTIFIER: - r = lease_parse_be32(option, len, &lease->server_address); - if (r < 0) - log_debug_errno(r, "Failed to parse server identifier, ignoring: %m"); - - break; - - case SD_DHCP_OPTION_SUBNET_MASK: - r = lease_parse_be32(option, len, &lease->subnet_mask); - if (r < 0) - log_debug_errno(r, "Failed to parse subnet mask, ignoring: %m"); - break; - - case SD_DHCP_OPTION_BROADCAST: - r = lease_parse_be32(option, len, &lease->broadcast); - if (r < 0) - log_debug_errno(r, "Failed to parse broadcast address, ignoring: %m"); - break; - - case SD_DHCP_OPTION_ROUTER: - r = lease_parse_in_addrs(option, len, &lease->router, &lease->router_size); - if (r < 0) - log_debug_errno(r, "Failed to parse router addresses, ignoring: %m"); - break; - - case SD_DHCP_OPTION_RAPID_COMMIT: - if (len > 0) - log_debug("Invalid DHCP Rapid Commit option, ignoring."); - lease->rapid_commit = true; - break; - - case SD_DHCP_OPTION_DOMAIN_NAME_SERVER: - r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_DNS].addr, &lease->servers[SD_DHCP_LEASE_DNS].size); - if (r < 0) - log_debug_errno(r, "Failed to parse DNS server, ignoring: %m"); - break; - - case SD_DHCP_OPTION_NTP_SERVER: - r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_NTP].addr, &lease->servers[SD_DHCP_LEASE_NTP].size); - if (r < 0) - log_debug_errno(r, "Failed to parse NTP server, ignoring: %m"); - break; - - case SD_DHCP_OPTION_SIP_SERVER: - r = lease_parse_sip_server(option, len, &lease->servers[SD_DHCP_LEASE_SIP].addr, &lease->servers[SD_DHCP_LEASE_SIP].size); - if (r < 0) - log_debug_errno(r, "Failed to parse SIP server, ignoring: %m"); - break; - - case SD_DHCP_OPTION_POP3_SERVER: - r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_POP3].addr, &lease->servers[SD_DHCP_LEASE_POP3].size); - if (r < 0) - log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m"); - break; - - case SD_DHCP_OPTION_SMTP_SERVER: - r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_SMTP].addr, &lease->servers[SD_DHCP_LEASE_SMTP].size); - if (r < 0) - log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m"); - break; - - case SD_DHCP_OPTION_LPR_SERVER: - r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_LPR].addr, &lease->servers[SD_DHCP_LEASE_LPR].size); - if (r < 0) - log_debug_errno(r, "Failed to parse LPR server, ignoring: %m"); - break; - - case SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL: - r = lease_parse_captive_portal(option, len, &lease->captive_portal); - if (r < 0) - log_debug_errno(r, "Failed to parse captive portal, ignoring: %m"); - break; - - case SD_DHCP_OPTION_STATIC_ROUTE: - r = lease_parse_static_routes(lease, option, len); - if (r < 0) - log_debug_errno(r, "Failed to parse static routes, ignoring: %m"); - break; - - case SD_DHCP_OPTION_MTU_INTERFACE: - r = lease_parse_u16(option, len, &lease->mtu, 68); - if (r < 0) - log_debug_errno(r, "Failed to parse MTU, ignoring: %m"); - if (lease->mtu < DHCP_MIN_PACKET_SIZE) { - log_debug("MTU value of %" PRIu16 " too small. Using default MTU value of %d instead.", lease->mtu, DHCP_MIN_PACKET_SIZE); - lease->mtu = DHCP_MIN_PACKET_SIZE; - } - - break; - - case SD_DHCP_OPTION_DOMAIN_NAME: - r = lease_parse_domain(option, len, &lease->domainname); - if (r < 0) { - log_debug_errno(r, "Failed to parse domain name, ignoring: %m"); - return 0; - } - - break; - - case SD_DHCP_OPTION_DOMAIN_SEARCH: - r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains); - if (r < 0) - log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m"); - break; - - case SD_DHCP_OPTION_HOST_NAME: - r = lease_parse_domain(option, len, &lease->hostname); - if (r < 0) { - log_debug_errno(r, "Failed to parse hostname, ignoring: %m"); - return 0; - } - - break; - - case SD_DHCP_OPTION_FQDN: - r = lease_parse_fqdn(option, len, &lease->fqdn); - if (r < 0) { - log_debug_errno(r, "Failed to parse FQDN, ignoring: %m"); - return 0; - } - - break; - - case SD_DHCP_OPTION_ROOT_PATH: { - _cleanup_free_ char *p = NULL; - - r = dhcp_option_parse_string(option, len, &p); - if (r < 0) - log_debug_errno(r, "Failed to parse root path, ignoring: %m"); - - free_and_replace(lease->root_path, p); - break; - } - case SD_DHCP_OPTION_RENEWAL_TIME: - r = lease_parse_be32_seconds(option, len, /* max_as_infinity= */ true, &lease->t1); - if (r < 0) - log_debug_errno(r, "Failed to parse T1 time, ignoring: %m"); - break; - - case SD_DHCP_OPTION_REBINDING_TIME: - r = lease_parse_be32_seconds(option, len, /* max_as_infinity= */ true, &lease->t2); - if (r < 0) - log_debug_errno(r, "Failed to parse T2 time, ignoring: %m"); - break; - - case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE: - r = lease_parse_classless_routes(lease, option, len); - if (r < 0) - log_debug_errno(r, "Failed to parse classless routes, ignoring: %m"); - break; - - case SD_DHCP_OPTION_TZDB_TIMEZONE: { - _cleanup_free_ char *tz = NULL; - - r = dhcp_option_parse_string(option, len, &tz); - if (r < 0) { - log_debug_errno(r, "Failed to parse timezone option, ignoring: %m"); - return 0; - } - - if (!timezone_is_valid(tz, LOG_DEBUG)) { - log_debug("Timezone is not valid, ignoring."); - return 0; - } - - free_and_replace(lease->timezone, tz); - - break; - } - - case SD_DHCP_OPTION_V4_DNR: - r = lease_parse_dnr(option, len, &lease->dnr, &lease->n_dnr); - if (r < 0) { - log_debug_errno(r, "Failed to parse network-designated resolvers, ignoring: %m"); - return 0; - } - - break; - - case SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION: - - if (len <= 0) - lease->vendor_specific = mfree(lease->vendor_specific); - else { - void *p; - - p = memdup(option, len); - if (!p) - return -ENOMEM; - - free_and_replace(lease->vendor_specific, p); - } - - lease->vendor_specific_len = len; - break; - - case SD_DHCP_OPTION_6RD: - r = lease_parse_6rd(lease, option, len); - if (r < 0) - log_debug_errno(r, "Failed to parse 6rd option, ignoring: %m"); - break; - - case SD_DHCP_OPTION_IPV6_ONLY_PREFERRED: - r = lease_parse_be32_seconds(option, len, /* max_as_infinity= */ false, &lease->ipv6_only_preferred_usec); - if (r < 0) - log_debug_errno(r, "Failed to parse IPv6 only preferred option, ignoring: %m"); - - else if (lease->ipv6_only_preferred_usec < MIN_V6ONLY_WAIT_USEC && - !network_test_mode_enabled()) - lease->ipv6_only_preferred_usec = MIN_V6ONLY_WAIT_USEC; - break; - - case SD_DHCP_OPTION_PRIVATE_BASE ... SD_DHCP_OPTION_PRIVATE_LAST: - r = dhcp_lease_insert_private_option(lease, code, option, len); - if (r < 0) - return r; - - break; - - default: - log_debug("Ignoring DHCP option %"PRIu8" while parsing.", code); - } - - return 0; -} - -/* Parses compressed domain names. */ -int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) { - _cleanup_strv_free_ char **names = NULL; - size_t pos = 0, cnt = 0; - int r; - - assert(domains); - assert(option || len == 0); - - if (len == 0) - return -EBADMSG; - - while (pos < len) { - _cleanup_free_ char *name = NULL; - size_t n = 0; - size_t jump_barrier = pos, next_chunk = 0; - bool first = true; - - for (;;) { - uint8_t c; - c = option[pos++]; - - if (c == 0) { - /* End of name */ - break; - } else if (c <= 63) { - const char *label; - - /* Literal label */ - label = (const char*) (option + pos); - pos += c; - if (pos >= len) - return -EBADMSG; - - if (!GREEDY_REALLOC(name, n + !first + DNS_LABEL_ESCAPED_MAX)) - return -ENOMEM; - - if (first) - first = false; - else - name[n++] = '.'; - - r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX); - if (r < 0) - return r; - - n += r; - } else if (FLAGS_SET(c, 0xc0)) { - /* Pointer */ - - uint8_t d; - uint16_t ptr; - - if (pos >= len) - return -EBADMSG; - - d = option[pos++]; - ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d; - - /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */ - if (ptr >= jump_barrier) - return -EBADMSG; - jump_barrier = ptr; - - /* Save current location so we don't end up re-parsing what's parsed so far. */ - if (next_chunk == 0) - next_chunk = pos; - - pos = ptr; - } else - return -EBADMSG; - } - - if (!GREEDY_REALLOC(name, n + 1)) - return -ENOMEM; - name[n] = 0; - - r = strv_extend(&names, name); - if (r < 0) - return r; - - cnt++; - - if (next_chunk != 0) - pos = next_chunk; - } - - strv_free_and_replace(*domains, names); - - return cnt; -} - -int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) { - struct sd_dhcp_raw_option *option, *before = NULL; - - assert(lease); - - LIST_FOREACH(options, cur, lease->private_options) { - if (tag < cur->tag) { - before = cur; - break; - } - if (tag == cur->tag) { - log_debug("Ignoring duplicate option, tagged %i.", tag); - return 0; - } - } - - option = new(struct sd_dhcp_raw_option, 1); - if (!option) - return -ENOMEM; - - option->tag = tag; - option->length = len; - option->data = memdup(data, len); - if (!option->data) { - free(option); - return -ENOMEM; - } - - LIST_INSERT_BEFORE(options, lease->private_options, before, option); - return 0; -} - int dhcp_lease_new(sd_dhcp_lease **ret) { sd_dhcp_lease *lease; @@ -1270,53 +391,6 @@ int dhcp_lease_new(sd_dhcp_lease **ret) { return 0; } -int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { - struct in_addr address, mask; - int r; - - assert(lease); - - if (lease->subnet_mask != INADDR_ANY) - return 0; - - if (lease->address == 0) - return -ENODATA; - - address.s_addr = lease->address; - - /* fall back to the default subnet masks based on address class */ - r = in4_addr_default_subnet_mask(&address, &mask); - if (r < 0) - return r; - - lease->subnet_mask = mask.s_addr; - - return 0; -} - -int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const sd_dhcp_client_id **ret) { - assert_return(lease, -EINVAL); - assert_return(ret, -EINVAL); - - if (!sd_dhcp_client_id_is_set(&lease->client_id)) - return -ENODATA; - - *ret = &lease->client_id; - - return 0; -} - -int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const sd_dhcp_client_id *client_id) { - assert_return(lease, -EINVAL); - - if (!sd_dhcp_client_id_is_set(client_id)) - return sd_dhcp_client_id_clear(&lease->client_id); - - lease->client_id = *client_id; - - return 0; -} - int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **ret) { assert_return(lease, -EINVAL); assert_return(ret, -EINVAL); diff --git a/src/libsystemd-network/test-sd-dhcp-lease.c b/src/libsystemd-network/test-sd-dhcp-lease.c deleted file mode 100644 index 32f9a6b9a3..0000000000 --- a/src/libsystemd-network/test-sd-dhcp-lease.c +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include "dhcp-lease-internal.h" -#include "strv.h" -#include "tests.h" - -/* According to RFC1035 section 4.1.4, a domain name in a message can be either: - * - a sequence of labels ending in a zero octet - * - a pointer - * - a sequence of labels ending with a pointer - */ -TEST(dhcp_lease_parse_search_domains_basic) { - int r; - _cleanup_strv_free_ char **domains = NULL; - static const uint8_t optionbuf[] = { - 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00, - 0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00, - }; - - r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains); - assert_se(r == 2); - assert_se(streq(domains[0], "FOO.BAR")); - assert_se(streq(domains[1], "ABCD.EFG")); -} - -TEST(dhcp_lease_parse_search_domains_ptr) { - int r; - _cleanup_strv_free_ char **domains = NULL; - static const uint8_t optionbuf[] = { - 0x03, 'F', 'O', 'O', 0x00, 0xC0, 0x00, - }; - - r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains); - assert_se(r == 2); - assert_se(streq(domains[0], "FOO")); - assert_se(streq(domains[1], "FOO")); -} - -TEST(dhcp_lease_parse_search_domains_labels_and_ptr) { - int r; - _cleanup_strv_free_ char **domains = NULL; - static const uint8_t optionbuf[] = { - 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00, - 0x03, 'A', 'B', 'C', 0xC0, 0x04, - }; - - r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains); - assert_se(r == 2); - assert_se(streq(domains[0], "FOO.BAR")); - assert_se(streq(domains[1], "ABC.BAR")); -} - -/* Tests for exceptions. */ - -TEST(dhcp_lease_parse_search_domains_no_data) { - _cleanup_strv_free_ char **domains = NULL; - static const uint8_t optionbuf[3] = {0, 0, 0}; - - assert_se(dhcp_lease_parse_search_domains(NULL, 0, &domains) == -EBADMSG); - assert_se(dhcp_lease_parse_search_domains(optionbuf, 0, &domains) == -EBADMSG); -} - -TEST(dhcp_lease_parse_search_domains_loops) { - _cleanup_strv_free_ char **domains = NULL; - static const uint8_t optionbuf[] = { - 0x03, 'F', 'O', 'O', 0x00, 0x03, 'B', 'A', 'R', 0xC0, 0x06, - }; - - assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains) == -EBADMSG); -} - -TEST(dhcp_lease_parse_search_domains_wrong_len) { - _cleanup_strv_free_ char **domains = NULL; - static const uint8_t optionbuf[] = { - 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00, - 0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00, - }; - - assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf) - 5, &domains) == -EBADMSG); -} - -DEFINE_TEST_MAIN(LOG_INFO); diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index 2dbee5450d..b4dd0cb1f6 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -56,26 +56,19 @@ int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_prefix(sd_dhcp_lease *lease, struct in_addr *ret_prefix, uint8_t *ret_prefixlen); int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr); -int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_server_type_t what, const struct in_addr **addr); int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr); -int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr); -int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr); -int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains); -int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname); -int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path); +int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **ret); int sd_dhcp_lease_get_captive_portal(sd_dhcp_lease *lease, const char **ret); int sd_dhcp_lease_get_dnr(sd_dhcp_lease *lease, sd_dns_resolver **ret_resolvers); 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 sd_dhcp_client_id **ret); int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **ret); int sd_dhcp_lease_get_6rd( sd_dhcp_lease *lease, From 4095391bd618a343364e0537f3057a3daaf8556a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 2 Apr 2026 04:20:59 +0900 Subject: [PATCH 6/6] dhcp-packet: drop unused dhcp_packet_verify_headers() --- src/libsystemd-network/dhcp-packet.c | 4 ---- src/libsystemd-network/dhcp-packet.h | 2 -- 2 files changed, 6 deletions(-) diff --git a/src/libsystemd-network/dhcp-packet.c b/src/libsystemd-network/dhcp-packet.c index 27b09a25bb..3186d93b7a 100644 --- a/src/libsystemd-network/dhcp-packet.c +++ b/src/libsystemd-network/dhcp-packet.c @@ -115,7 +115,3 @@ int dhcp_packet_append_ip_headers( packet->udp = udp; return 0; } - -int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port) { - return udp_packet_verify(&IOVEC_MAKE(packet, len), port, checksum, /* ret_payload= */ NULL); -} diff --git a/src/libsystemd-network/dhcp-packet.h b/src/libsystemd-network/dhcp-packet.h index 90ea2caac9..fceeb6473b 100644 --- a/src/libsystemd-network/dhcp-packet.h +++ b/src/libsystemd-network/dhcp-packet.h @@ -31,5 +31,3 @@ int dhcp_packet_append_ip_headers( uint16_t destination, uint16_t len, int ip_service_type); - -int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);