chiark / gitweb /
dhcp-lease: add support for parsing a few more dhcp options
authorTom Gundersen <teg@jklm.no>
Tue, 20 May 2014 20:02:49 +0000 (22:02 +0200)
committerTom Gundersen <teg@jklm.no>
Tue, 20 May 2014 21:31:22 +0000 (23:31 +0200)
src/libsystemd-network/dhcp-lease-internal.h
src/libsystemd-network/dhcp-protocol.h
src/libsystemd-network/sd-dhcp-lease.c

index 297bacb..ff09583 100644 (file)
 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;
index 11de186..260508f 100644 (file)
@@ -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,
index 2ec45ca..3203b7a 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)
@@ -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;