summaryrefslogtreecommitdiff
path: root/sbin/dhclient
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/dhclient')
-rw-r--r--sbin/dhclient/clparse.c5
-rw-r--r--sbin/dhclient/dhclient.c103
-rw-r--r--sbin/dhclient/dhcp.h3
-rw-r--r--sbin/dhclient/kroute.c39
-rw-r--r--sbin/dhclient/tables.c4
5 files changed, 112 insertions, 42 deletions
diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c
index 1dab99a1de1..b3f198fed2a 100644
--- a/sbin/dhclient/clparse.c
+++ b/sbin/dhclient/clparse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clparse.c,v 1.59 2013/06/09 00:30:06 krw Exp $ */
+/* $OpenBSD: clparse.c,v 1.60 2013/06/09 16:21:50 krw Exp $ */
/* Parser for dhclient config and lease files. */
@@ -72,6 +72,9 @@ read_client_conf(void)
[config->requested_option_count++] = DHO_BROADCAST_ADDRESS;
config->requested_options
[config->requested_option_count++] = DHO_TIME_OFFSET;
+ /* RFC 3442 says CLASSLESS_STATIC_ROUTES must be before ROUTERS! */
+ config->requested_options
+ [config->requested_option_count++] = DHO_CLASSLESS_STATIC_ROUTES;
config->requested_options
[config->requested_option_count++] = DHO_ROUTERS;
config->requested_options
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index d7f5a86c7cf..16dd15ac8c7 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.251 2013/06/09 15:06:34 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.252 2013/06/09 16:21:50 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -109,6 +109,8 @@ void socket_nonblockmode(int);
void apply_ignore_list(char *);
void add_default_route(int, struct in_addr, struct in_addr);
+void add_static_routes(int, struct option_data *);
+void add_classless_static_routes(int, struct option_data *);
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -790,12 +792,21 @@ bind_lease(void)
* is done by the RTM_NEWADDR message being received.
*/
add_address(ifi->name, ifi->rdomain, client->new->address, mask);
- if (options[DHO_ROUTERS].len) {
- memset(&gateway, 0, sizeof(gateway));
- /* XXX Only use FIRST router address for now. */
- memcpy(&gateway.s_addr, options[DHO_ROUTERS].data,
- options[DHO_ROUTERS].len);
- add_default_route(ifi->rdomain, client->new->address, gateway);
+ if (options[DHO_CLASSLESS_STATIC_ROUTES].len) {
+ add_classless_static_routes(ifi->rdomain,
+ &options[DHO_CLASSLESS_STATIC_ROUTES]);
+ } else {
+ if (options[DHO_ROUTERS].len) {
+ memset(&gateway, 0, sizeof(gateway));
+ /* XXX Only use FIRST router address for now. */
+ memcpy(&gateway.s_addr, options[DHO_ROUTERS].data,
+ options[DHO_ROUTERS].len);
+ add_default_route(ifi->rdomain, client->new->address,
+ gateway);
+ }
+ if (options[DHO_STATIC_ROUTES].len)
+ add_static_routes(ifi->rdomain,
+ &options[DHO_STATIC_ROUTES]);
}
client->new->resolv_conf = resolv_conf_contents(
@@ -2280,27 +2291,77 @@ priv_write_file(struct imsg_write_file *imsg)
void
add_default_route(int rdomain, struct in_addr addr, struct in_addr gateway)
{
- struct imsg_add_route imsg;
- int rslt;
+ struct in_addr netmask, dest;
+ int addrs;
- memset(&imsg, 0, sizeof(imsg));
-
- imsg.rdomain = rdomain;
- imsg.dest = addr;
- imsg.addrs = RTA_DST | RTA_NETMASK;
+ memset(&netmask, 0, sizeof(netmask));
+ memset(&dest, 0, sizeof(dest));
+ addrs = RTA_DST | RTA_NETMASK;
/*
* Set gateway address if and only if non-zero addr supplied. A
* gateway address of 0 implies '-iface'.
*/
- if (bcmp(&gateway, &addr, sizeof(addr)) != 0) {
- imsg.gateway = gateway;
- imsg.addrs |= RTA_GATEWAY;
+ if (bcmp(&gateway, &addr, sizeof(addr)) != 0)
+ addrs |= RTA_GATEWAY;
+
+ add_route(rdomain, dest, netmask, gateway, addrs);
+}
+
+void
+add_static_routes(int rdomain, struct option_data *static_routes)
+{
+ struct in_addr dest, netmask, gateway;
+ u_int8_t *addr;
+ int i;
+
+ memset(&netmask, 0, sizeof(netmask)); /* Always 0 for class addrs. */
+
+ for (i = 0; (i + 7) < static_routes->len; i += 8) {
+ addr = &static_routes->data[i];
+ memset(&dest, 0, sizeof(dest));
+ memset(&gateway, 0, sizeof(gateway));
+
+ memcpy(&dest.s_addr, addr, 4);
+ if (dest.s_addr == INADDR_ANY)
+ continue; /* RFC 2132 says 0.0.0.0 is not allowed. */
+ memcpy(&gateway.s_addr, addr+4, 4);
+
+ /* XXX Order implies priority but we're ignoring that. */
+ add_route(rdomain, dest, netmask, gateway,
+ RTA_DST | RTA_GATEWAY);
}
+}
- rslt = imsg_compose(unpriv_ibuf, IMSG_ADD_ROUTE, 0, 0, -1, &imsg,
- sizeof(imsg));
+void add_classless_static_routes(int rdomain,
+ struct option_data *classless_static_routes)
+{
+ struct in_addr dest, netmask, gateway;
+ int bits, bytes, i;
- if (rslt == -1)
- warning("add_route: imsg_compose: %s", strerror(errno));
+ i = 0;
+ while (i < classless_static_routes->len) {
+ bits = classless_static_routes->data[i];
+ bytes = (bits + 7) / 8;
+ i++;
+
+ memset(&netmask, 0, sizeof(netmask));
+ if (bits)
+ netmask.s_addr = htonl(0xffffffff << (32 - bits));
+
+ memset(&dest, 0, sizeof(dest));
+ memcpy(&dest, &classless_static_routes->data[i], bytes);
+ dest.s_addr = dest.s_addr & netmask.s_addr;
+ i += bytes;
+
+ memset(&gateway, 0, sizeof(gateway));
+ memcpy(&gateway, &classless_static_routes->data[i], 4);
+ i += 4;
+
+ if (gateway.s_addr == INADDR_ANY)
+ continue; /* OBSD TCP/IP doesn't support this. */
+
+ add_route(rdomain, dest, netmask, gateway,
+ RTA_DST | RTA_GATEWAY | RTA_NETMASK);
+ }
}
diff --git a/sbin/dhclient/dhcp.h b/sbin/dhclient/dhcp.h
index 1e24aa6fa34..53f8a0440fa 100644
--- a/sbin/dhclient/dhcp.h
+++ b/sbin/dhclient/dhcp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcp.h,v 1.14 2013/06/09 00:30:06 krw Exp $ */
+/* $OpenBSD: dhcp.h,v 1.15 2013/06/09 16:21:50 krw Exp $ */
/* Protocol structures. */
@@ -173,6 +173,7 @@ struct dhcp_packet {
#define DHO_NDS_SERVERS 85
#define DHO_NDS_TREE_NAME 86
#define DHO_NDS_CONTEXT 87
+#define DHO_CLASSLESS_STATIC_ROUTES 121
#define DHO_TFTP_CONFIG_FILE 144
#define DHO_VOIP_CONFIGURATION_SERVER 150
#define DHO_AUTOPROXY_SCRIPT 252
diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c
index 1abef0d79ff..2a3321c5aab 100644
--- a/sbin/dhclient/kroute.c
+++ b/sbin/dhclient/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.51 2013/06/09 15:06:34 krw Exp $ */
+/* $OpenBSD: kroute.c,v 1.52 2013/06/09 16:21:50 krw Exp $ */
/*
* Copyright 2012 Kenneth R Westerback <krw@openbsd.org>
@@ -229,18 +229,21 @@ priv_add_route(struct imsg_add_route *imsg)
iov[iovcnt].iov_base = &rtm;
iov[iovcnt++].iov_len = sizeof(rtm);
- /* Set destination address of all zeros. */
+ /* Set destination address. */
memset(&dest, 0, sizeof(dest));
- dest.sin_len = sizeof(dest);
- dest.sin_family = AF_INET;
+ if (imsg->addrs & RTA_DST) {
+ dest.sin_len = sizeof(dest);
+ dest.sin_family = AF_INET;
+ dest.sin_addr.s_addr = imsg->dest.s_addr;
- rtm.rtm_addrs |= RTA_DST;
- rtm.rtm_msglen += sizeof(dest);
+ rtm.rtm_addrs |= RTA_DST;
+ rtm.rtm_msglen += sizeof(dest);
- iov[iovcnt].iov_base = &dest;
- iov[iovcnt++].iov_len = sizeof(dest);
+ iov[iovcnt].iov_base = &dest;
+ iov[iovcnt++].iov_len = sizeof(dest);
+ }
/*
* Set gateway address if and only if non-zero addr supplied. A
@@ -248,7 +251,7 @@ priv_add_route(struct imsg_add_route *imsg)
*/
memset(&gateway, 0, sizeof(gateway));
- if ((imsg->addrs & RTA_GATEWAY) != 0) {
+ if (imsg->addrs & RTA_GATEWAY) {
gateway.sin_len = sizeof(gateway);
gateway.sin_family = AF_INET;
gateway.sin_addr.s_addr = imsg->gateway.s_addr;
@@ -261,18 +264,20 @@ priv_add_route(struct imsg_add_route *imsg)
iov[iovcnt++].iov_len = sizeof(gateway);
}
- /* Add netmask of 0. */
+ /* Add netmask. */
memset(&mask, 0, sizeof(mask));
- mask.sin_len = sizeof(mask);
- mask.sin_family = AF_INET;
- mask.sin_addr.s_addr = imsg->netmask.s_addr;
+ if (imsg->addrs & RTA_NETMASK) {
+ mask.sin_len = sizeof(mask);
+ mask.sin_family = AF_INET;
+ mask.sin_addr.s_addr = imsg->netmask.s_addr;
- rtm.rtm_addrs |= RTA_NETMASK;
- rtm.rtm_msglen += sizeof(mask);
+ rtm.rtm_addrs |= RTA_NETMASK;
+ rtm.rtm_msglen += sizeof(mask);
- iov[iovcnt].iov_base = &mask;
- iov[iovcnt++].iov_len = sizeof(mask);
+ iov[iovcnt].iov_base = &mask;
+ iov[iovcnt++].iov_len = sizeof(mask);
+ }
/* Add our label so we can identify the route as our creation. */
if (create_route_label(&label) == 0) {
diff --git a/sbin/dhclient/tables.c b/sbin/dhclient/tables.c
index b9112334589..5ccfe34254c 100644
--- a/sbin/dhclient/tables.c
+++ b/sbin/dhclient/tables.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.c,v 1.15 2013/06/09 00:30:06 krw Exp $ */
+/* $OpenBSD: tables.c,v 1.16 2013/06/09 16:21:50 krw Exp $ */
/* Tables of information. */
@@ -182,7 +182,7 @@ const struct option dhcp_options[256] = {
/* 118 */ { "option-118", "X" },
/* 119 */ { "option-119", "X" },
/* 120 */ { "option-120", "X" },
- /* 121 */ { "option-121", "X" },
+ /* 121 */ { "classless-static-routes", "X" },
/* 122 */ { "option-122", "X" },
/* 123 */ { "option-123", "X" },
/* 124 */ { "option-124", "X" },