summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/network-internal.c
diff options
context:
space:
mode:
authorEugene Yakubovich <eyakubovich@gmail.com>2014-06-27 15:00:06 -0700
committerTom Gundersen <teg@jklm.no>2014-06-29 15:18:21 +0200
commite1ea665edac17d75fce01b72dadfa3211b60df2c (patch)
tree9f1d4c8ae93862cf5ebae973cd48d053ef34c0dd /src/libsystemd-network/network-internal.c
parented942a9eb22d50f667909ad6184b45015d28d054 (diff)
Add support for DHCP static route options
This adds support for DHCP options 33 and 121: Static Route and Classless Static Route. To enable this feature, set UseRoutes=true in .network file. Returned routes are added to the routing table.
Diffstat (limited to 'src/libsystemd-network/network-internal.c')
-rw-r--r--src/libsystemd-network/network-internal.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 97217c12e..a5db0c535 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -28,6 +28,7 @@
#include "siphash24.h"
#include "libudev-private.h"
#include "network-internal.h"
+#include "dhcp-lease-internal.h"
#include "log.h"
#include "utf8.h"
#include "util.h"
@@ -432,3 +433,88 @@ int deserialize_in6_addrs(struct in6_addr **ret, size_t *ret_size, const char *s
return 0;
}
+
+void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) {
+ unsigned i;
+
+ assert(f);
+ assert(key);
+ assert(routes);
+ assert(size);
+
+ fprintf(f, "%s=", key);
+
+ for (i = 0; i < size; i++)
+ fprintf(f, "%s/%" PRIu8 ",%s%s", inet_ntoa(routes[i].dst_addr),
+ routes[i].dst_prefixlen, inet_ntoa(routes[i].gw_addr),
+ (i < (size - 1)) ? " ": "");
+
+ fputs("\n", f);
+}
+
+int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
+ _cleanup_free_ struct sd_dhcp_route *routes = NULL;
+ size_t size = 0, allocated = 0;
+ char *word, *state;
+ size_t len;
+
+ assert(ret);
+ assert(ret_size);
+ assert(ret_allocated);
+ assert(string);
+
+ FOREACH_WORD(word, len, string, state) {
+ /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
+ _cleanup_free_ char* entry;
+ char *tok, *tok_end;
+ unsigned n;
+ int r;
+
+ if (!GREEDY_REALLOC(routes, allocated, size + 1))
+ return -ENOMEM;
+
+ entry = strndup(word, len);
+
+ tok = entry;
+
+ /* get the subnet */
+ tok_end = strchr(tok, '/');
+ if (!tok_end)
+ continue;
+ *tok_end = '\0';
+
+ r = inet_aton(tok, &routes[size].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;
+
+ routes[size].dst_prefixlen = (uint8_t) n;
+ tok = tok_end + 1;
+
+ /* get the gateway */
+ r = inet_aton(tok, &routes[size].gw_addr);
+ if (r == 0)
+ continue;
+
+ size++;
+ }
+
+ *ret_size = size;
+ *ret_allocated = allocated;
+ *ret = routes;
+ routes = NULL;
+
+ return 0;
+}