summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-05-20 22:02:49 +0200
committerTom Gundersen <teg@jklm.no>2014-05-20 23:31:22 +0200
commitf5c0c00f400e6f1fa58c5faf8bc93ca9057d4463 (patch)
tree4fe97afcb57778c64617e51c507a51c764a92528 /src
parente140ae58f1c10bbd75ef94afc07d07b82323b506 (diff)
dhcp-lease: add support for parsing a few more dhcp options
Diffstat (limited to 'src')
-rw-r--r--src/libsystemd-network/dhcp-lease-internal.h12
-rw-r--r--src/libsystemd-network/dhcp-protocol.h10
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c90
3 files changed, 110 insertions, 2 deletions
diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h
index 297bacbb78..ff09583604 100644
--- a/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/libsystemd-network/dhcp-lease-internal.h
@@ -35,19 +35,31 @@
struct sd_dhcp_lease {
RefCount n_ref;
+ int32_t time_offset;
uint32_t t1;
uint32_t t2;
uint32_t lifetime;
+ uint32_t mtu_aging_timeout;
be32_t address;
be32_t server_address;
be32_t subnet_mask;
be32_t router;
be32_t next_server;
+ be32_t broadcast;
struct in_addr *dns;
size_t dns_size;
struct in_addr *ntp;
size_t ntp_size;
+ struct in_addr *policy_filter;
+ size_t policy_filter_size;
+ struct in_addr *static_route;
+ size_t static_route_size;
+ uint16_t boot_file_size;
+ uint16_t mdr;
uint16_t mtu;
+ uint8_t ttl;
+ bool ip_forward;
+ bool ip_forward_non_local;
char *domainname;
char *hostname;
char *root_path;
diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h
index 11de186297..260508fbbd 100644
--- a/src/libsystemd-network/dhcp-protocol.h
+++ b/src/libsystemd-network/dhcp-protocol.h
@@ -105,12 +105,22 @@ enum {
enum {
DHCP_OPTION_PAD = 0,
DHCP_OPTION_SUBNET_MASK = 1,
+ DHCP_OPTION_TIME_OFFSET = 2,
DHCP_OPTION_ROUTER = 3,
DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
DHCP_OPTION_HOST_NAME = 12,
+ DHCP_OPTION_BOOT_FILE_SIZE = 13,
DHCP_OPTION_DOMAIN_NAME = 15,
DHCP_OPTION_ROOT_PATH = 17,
+ DHCP_OPTION_ENABLE_IP_FORWARDING = 19,
+ DHCP_OPTION_ENABLE_IP_FORWARDING_NL = 20,
+ DHCP_OPTION_POLICY_FILTER = 21,
+ DHCP_OPTION_INTERFACE_MDR = 22,
+ DHCP_OPTION_INTERFACE_TTL = 23,
+ DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
DHCP_OPTION_INTERFACE_MTU = 26,
+ DHCP_OPTION_BROADCAST = 28,
+ DHCP_OPTION_STATIC_ROUTE = 33,
DHCP_OPTION_NTP_SERVER = 42,
DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 2ec45ca949..3203b7a592 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -196,6 +196,10 @@ static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, ui
}
}
+static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) {
+ lease_parse_u32(option, len, (uint32_t *)ret, 0);
+}
+
static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) {
be16_t val;
@@ -219,6 +223,26 @@ static void lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) {
memcpy(ret, option, 4);
}
+static void lease_parse_bool(const uint8_t *option, size_t len, bool *ret) {
+ assert(option);
+ assert(ret);
+
+ if (len == 1)
+ *ret = !!(*option);
+}
+
+static void lease_parse_u8(const uint8_t *option, size_t len, uint8_t *ret, uint8_t min) {
+ assert(option);
+ assert(ret);
+
+ if (len == 1) {
+ *ret = *option;
+
+ if (*ret < min)
+ *ret = min;
+ }
+}
+
static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
assert(option);
assert(ret);
@@ -237,12 +261,12 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
return 0;
}
-static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
+static int lease_parse_in_addrs_aux(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size, size_t mult) {
assert(option);
assert(ret);
assert(ret_size);
- if (len && !(len % 4)) {
+ if (len && !(len % (4 * mult))) {
size_t size;
struct in_addr *addresses;
@@ -260,6 +284,14 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
return 0;
}
+static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
+ return lease_parse_in_addrs_aux(option, len, ret, ret_size, 1);
+}
+
+static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
+ return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2);
+}
+
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
void *user_data) {
sd_dhcp_lease *lease = user_data;
@@ -269,6 +301,16 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
switch(code) {
+ case DHCP_OPTION_TIME_OFFSET:
+ lease_parse_s32(option, len, &lease->time_offset);
+
+ break;
+
+ case DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT:
+ lease_parse_u32(option, len, &lease->mtu_aging_timeout, 0);
+
+ break;
+
case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
lease_parse_u32(option, len, &lease->lifetime, 1);
@@ -284,6 +326,11 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
break;
+ case DHCP_OPTION_BROADCAST:
+ lease_parse_be32(option, len, &lease->broadcast);
+
+ break;
+
case DHCP_OPTION_ROUTER:
lease_parse_be32(option, len, &lease->router);
@@ -303,11 +350,40 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
break;
+ case DHCP_OPTION_POLICY_FILTER:
+ r = lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size);
+ if (r < 0)
+ return r;
+
+ break;
+
+ case DHCP_OPTION_STATIC_ROUTE:
+ r = lease_parse_in_addrs_pairs(option, len, &lease->static_route, &lease->static_route_size);
+ if (r < 0)
+ return r;
+
+ break;
+
case DHCP_OPTION_INTERFACE_MTU:
lease_parse_u16(option, len, &lease->mtu, 68);
break;
+ case DHCP_OPTION_INTERFACE_MDR:
+ lease_parse_u16(option, len, &lease->mdr, 576);
+
+ break;
+
+ case DHCP_OPTION_INTERFACE_TTL:
+ lease_parse_u8(option, len, &lease->ttl, 1);
+
+ break;
+
+ case DHCP_OPTION_BOOT_FILE_SIZE:
+ lease_parse_u16(option, len, &lease->boot_file_size, 0);
+
+ break;
+
case DHCP_OPTION_DOMAIN_NAME:
r = lease_parse_string(option, len, &lease->domainname);
if (r < 0)
@@ -338,6 +414,16 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
lease_parse_u32(option, len, &lease->t2, 1);
break;
+
+ case DHCP_OPTION_ENABLE_IP_FORWARDING:
+ lease_parse_bool(option, len, &lease->ip_forward);
+
+ break;
+
+ case DHCP_OPTION_ENABLE_IP_FORWARDING_NL:
+ lease_parse_bool(option, len, &lease->ip_forward_non_local);
+
+ break;
}
return 0;