chiark / gitweb /
dhcp-lease: add support for parsing a few more dhcp options
[elogind.git] / src / libsystemd-network / sd-dhcp-lease.c
index 2ec45ca949b01c89ea888599b9d818aa5dddba69..3203b7a592661d451650a859d1804b7583bebb3b 100644 (file)
@@ -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)
@@ -337,6 +413,16 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
         case DHCP_OPTION_REBINDING_T2_TIME:
                 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;
         }