}
static int lease_parse_routes(
- const uint8_t *option, size_t len,
- struct sd_dhcp_route **routes, size_t *routes_size) {
+ const uint8_t *option,
+ size_t len,
+ struct sd_dhcp_route **routes,
+ size_t *routes_size) {
- struct in_addr addr;
+ int r;
assert(option || len <= 0);
assert(routes);
assert(routes_size);
- if (len <= 0)
- return 0;
-
if (len % 8 != 0)
return -EINVAL;
- if (!GREEDY_REALLOC(*routes, *routes_size + (len / 8)))
- return -ENOMEM;
-
while (len >= 8) {
- struct sd_dhcp_route *route = *routes + *routes_size;
- int r;
+ struct in_addr dst, gw;
+ uint8_t prefixlen;
- route->option = SD_DHCP_OPTION_STATIC_ROUTE;
- r = in4_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen);
- if (r < 0) {
- log_debug("Failed to determine destination prefix length from class based IP, ignoring");
- continue;
- }
-
- assert_se(lease_parse_be32(option, 4, &addr.s_addr) >= 0);
- route->dst_addr = inet_makeaddr(inet_netof(addr), 0);
+ assert_se(lease_parse_be32(option, 4, &dst.s_addr) >= 0);
option += 4;
- assert_se(lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0);
+ 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)
+ return -EINVAL;
+
+ (void) in4_addr_mask(&dst, prefixlen);
+
+ if (!GREEDY_REALLOC(*routes, *routes_size + 1))
+ return -ENOMEM;
+
+ (*routes)[*routes_size] = (struct sd_dhcp_route) {
+ .dst_addr = dst,
+ .gw_addr = gw,
+ .dst_prefixlen = prefixlen,
+ .option = SD_DHCP_OPTION_STATIC_ROUTE,
+ };
+
(*routes_size)++;
}
pos = next_chunk;
}
- *domains = TAKE_PTR(names);
+ strv_free_and_replace(*domains, names);
return cnt;
}
return 0;
}
+static char **private_options_free(char **options) {
+ if (!options)
+ return NULL;
+
+ for (unsigned i = 0; i < SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1; i++)
+ free(options[i]);
+
+ 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
*vendor_specific_hex = NULL,
*lifetime = NULL,
*t1 = NULL,
- *t2 = NULL,
- *options[SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1] = {};
+ *t2 = NULL;
+ _cleanup_(private_options_freep) char **options = NULL;
int r, i;
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,