int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *vendor_class) {
_cleanup_free_ uint8_t *p = NULL;
- uint32_t enterprise_identifier;
- size_t total, offset;
+ size_t n = 0;
assert(buf);
assert(*buf);
if (strv_isempty(vendor_class))
return 0;
- enterprise_identifier = htobe32(SYSTEMD_PEN);
-
- p = memdup(&enterprise_identifier, sizeof(enterprise_identifier));
- if (!p)
+ if (!GREEDY_REALLOC(p, sizeof(be32_t)))
return -ENOMEM;
- total = sizeof(enterprise_identifier);
- offset = total;
+ /* Enterprise Identifier */
+ unaligned_write_be32(p, SYSTEMD_PEN);
+ n += sizeof(be32_t);
STRV_FOREACH(s, vendor_class) {
size_t len = strlen(*s);
- uint8_t *q;
if (len > UINT16_MAX || len == 0)
return -EINVAL;
- q = realloc(p, total + len + 2);
- if (!q)
+ if (!GREEDY_REALLOC(p, n + len + 2))
return -ENOMEM;
- p = q;
-
- unaligned_write_be16(&p[offset], len);
- memcpy(&p[offset + 2], *s, len);
-
- offset += 2 + len;
- total += 2 + len;
+ unaligned_write_be16(p + n, len);
+ memcpy(p + n + 2, *s, len);
+ n += len + 2;
}
- return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_CLASS, total, p);
+ return dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_CLASS, n, p);
}
int dhcp6_option_parse(