summaryrefslogtreecommitdiff
path: root/src/libsystemd-network
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/network-internal.c15
-rw-r--r--src/libsystemd-network/network-internal.h4
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c44
3 files changed, 54 insertions, 9 deletions
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index a4d4f1ae2f..5da06435ed 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -437,7 +437,7 @@ int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
return size;
}
-void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) {
+void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size) {
unsigned i;
assert(f);
@@ -448,10 +448,15 @@ void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *route
fprintf(f, "%s=", key);
for (i = 0; i < size; i++) {
- fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr),
- routes[i].dst_prefixlen);
- fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr),
- (i < (size - 1)) ? " ": "");
+ 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/%" PRIu8, inet_ntoa(dest), length);
+ fprintf(f, ",%s%s", inet_ntoa(gw), (i < (size - 1)) ? " ": "");
}
fputs("\n", f);
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 8a30921966..c43c01accf 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -23,6 +23,8 @@
#include <stdbool.h>
+#include "sd-dhcp-lease.h"
+
#include "condition.h"
#include "udev.h"
@@ -74,7 +76,7 @@ int deserialize_in6_addrs(struct in6_addr **addresses, 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;
-void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size);
+void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size);
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 6fb80dda7a..a3c3e316b3 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -206,14 +206,28 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
return 0;
}
-int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) {
+/*
+ * The returned routes array must be freed by the caller.
+ * Route objects have the same lifetime of the lease and must not be freed.
+ */
+int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
+ sd_dhcp_route **ret;
+ unsigned i;
+
assert_return(lease, -EINVAL);
assert_return(routes, -EINVAL);
if (lease->static_route_size <= 0)
return -ENODATA;
- *routes = lease->static_route;
+ ret = new(sd_dhcp_route *, lease->static_route_size);
+ if (!ret)
+ return -ENOMEM;
+
+ for (i = 0; i < lease->static_route_size; i++)
+ ret[i] = &lease->static_route[i];
+
+ *routes = ret;
return (int) lease->static_route_size;
}
@@ -723,7 +737,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
size_t client_id_len, data_len;
const char *string;
uint16_t mtu;
- struct sd_dhcp_route *routes;
+ _cleanup_free_ sd_dhcp_route **routes = NULL;
uint32_t t1, t2, lifetime;
int r;
@@ -1142,3 +1156,27 @@ int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **tz) {
*tz = lease->timezone;
return 0;
}
+
+int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination) {
+ assert_return(route, -EINVAL);
+ assert_return(destination, -EINVAL);
+
+ *destination = route->dst_addr;
+ return 0;
+}
+
+int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length) {
+ assert_return(route, -EINVAL);
+ assert_return(length, -EINVAL);
+
+ *length = route->dst_prefixlen;
+ return 0;
+}
+
+int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) {
+ assert_return(route, -EINVAL);
+ assert_return(gateway, -EINVAL);
+
+ *gateway = route->gw_addr;
+ return 0;
+}