summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChristian Mehlis <christian@m3hlis.de>2014-08-12 14:58:06 +0200
committerChristian Mehlis <christian@m3hlis.de>2014-08-12 14:58:06 +0200
commitf2cda6c15b55c80be8739f492a8ee7b4dbd1cf52 (patch)
treea2095d9dec4fb67c6de995e47c9664013bbd2aec
parent634d9fe9142f62b7b2e7647ef88d6606e54ab155 (diff)
dhcpv4: implement router configuration option
RFC 2132 defines: 3.5. Router Option The router option specifies a list of IP addresses for routers on the client's subnet. Routers SHOULD be listed in order of preference. The code for the router option is 3. The minimum length for the router option is 4 octets, and the length MUST always be a multiple of 4. Code Len Address 1 Address 2 +-----+-----+-----+-----+-----+-----+-----+-----+-- | 3 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... +-----+-----+-----+-----+-----+-----+-----+-----+--
-rw-r--r--README2
-rw-r--r--src/config.c25
-rw-r--r--src/dhcpv4.c7
-rw-r--r--src/odhcpd.h2
4 files changed, 34 insertions, 2 deletions
diff --git a/README b/README
index 6011b0f..b86df25 100644
--- a/README
+++ b/README
@@ -85,6 +85,8 @@ ndp string disabled Neighbor Discovery Proxy
dynamicdhcp bool 1 dynamically create leases
for DHCPv4 and DHCPv6
+router list <local address> Routers to announce
+ accepts IPv4 only
dns list <local address> DNS servers to announce
accepts IPv4 and IPv6
domain list <local search domain> Search domains to announce
diff --git a/src/config.c b/src/config.c
index 068d1a7..835db13 100644
--- a/src/config.c
+++ b/src/config.c
@@ -30,6 +30,7 @@ enum {
IFACE_ATTR_DHCPV4,
IFACE_ATTR_DHCPV6,
IFACE_ATTR_NDP,
+ IFACE_ATTR_ROUTER,
IFACE_ATTR_DNS,
IFACE_ATTR_DOMAIN,
IFACE_ATTR_FILTER_CLASS,
@@ -61,6 +62,7 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
[IFACE_ATTR_DHCPV4] = { .name = "dhcpv4", .type = BLOBMSG_TYPE_STRING },
[IFACE_ATTR_DHCPV6] = { .name = "dhcpv6", .type = BLOBMSG_TYPE_STRING },
[IFACE_ATTR_NDP] = { .name = "ndp", .type = BLOBMSG_TYPE_STRING },
+ [IFACE_ATTR_ROUTER] = { .name = "router", .type = BLOBMSG_TYPE_ARRAY },
[IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY },
[IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY },
[IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING },
@@ -152,6 +154,7 @@ static void clean_interface(struct interface *iface)
free(iface->search);
free(iface->upstream);
free(iface->static_ndp);
+ free(iface->dhcpv4_router);
free(iface->dhcpv4_dns);
free(iface->dhcpv6_raw);
free(iface->filter_class);
@@ -409,6 +412,28 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
goto err;
}
+ if ((c = tb[IFACE_ATTR_ROUTER])) {
+ struct blob_attr *cur;
+ unsigned rem;
+
+ blobmsg_for_each_attr(cur, c, rem) {
+ if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, NULL))
+ continue;
+
+ struct in_addr addr4;
+ if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) {
+ iface->dhcpv4_router = realloc(iface->dhcpv4_router,
+ (++iface->dhcpv4_router_cnt) * sizeof(*iface->dhcpv4_router));
+ if (!iface->dhcpv4_router)
+ goto err;
+
+ iface->dhcpv4_router[iface->dhcpv4_router_cnt - 1] = addr4;
+ } else {
+ goto err;
+ }
+ }
+ }
+
if ((c = tb[IFACE_ATTR_DNS])) {
struct blob_attr *cur;
unsigned rem;
diff --git a/src/dhcpv4.c b/src/dhcpv4.c
index 2093ecd..7b200cd 100644
--- a/src/dhcpv4.c
+++ b/src/dhcpv4.c
@@ -384,8 +384,11 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
len, search_buf);
}
- dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER, 4, &ifaddr.sin_addr);
-
+ if (iface->dhcpv4_router_cnt == 0)
+ dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER, 4, &ifaddr.sin_addr);
+ else
+ dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER,
+ 4 * iface->dhcpv4_router_cnt, iface->dhcpv4_router);
if (iface->dhcpv4_dns_cnt == 0)
diff --git a/src/odhcpd.h b/src/odhcpd.h
index b2b38dc..4c0c28c 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -147,6 +147,8 @@ struct interface {
// DHCPv4
struct in_addr dhcpv4_start;
struct in_addr dhcpv4_end;
+ struct in_addr *dhcpv4_router;
+ size_t dhcpv4_router_cnt;
struct in_addr *dhcpv4_dns;
size_t dhcpv4_dns_cnt;
uint32_t dhcpv4_leasetime;