+static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
+ be32_t val;
+
+ assert(option);
+ assert(ret);
+
+ if (len == 4) {
+ memcpy(&val, option, 4);
+ *ret = be32toh(val);
+
+ if (*ret < min)
+ *ret = min;
+ }
+}
+
+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;
+
+ assert(option);
+ assert(ret);
+
+ if (len == 2) {
+ memcpy(&val, option, 2);
+ *ret = be16toh(val);
+
+ if (*ret < min)
+ *ret = min;
+ }
+}
+
+static void lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) {
+ assert(option);
+ assert(ret);
+
+ if (len == 4)
+ 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);
+
+ if (len >= 1) {
+ char *string;
+
+ string = strndup((const char *)option, len);
+ if (!string)
+ return -errno;
+
+ free(*ret);
+ *ret = string;
+ }
+
+ return 0;
+}
+
+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 * mult))) {
+ size_t size;
+ struct in_addr *addresses;
+
+ size = len / 4;
+
+ addresses = newdup(struct in_addr, option, size);
+ if (!addresses)
+ return -ENOMEM;
+
+ free(*ret);
+ *ret = addresses;
+ *ret_size = size;
+ }
+
+ 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);
+}
+