+
+ uint8_t *ia_pd = alloca(ia_pd_entries * (sizeof(struct dhcpv6_ia_prefix) + 10));
+ for (size_t i = 0; i < ia_pd_entries; ++i) {
+ uint8_t ex_len = 0;
+ if (e[i].priority > 0)
+ ex_len = ((e[i].priority - e[i].length - 1) / 8) + 6;
+
+ struct dhcpv6_ia_prefix p = {
+ .type = htons(DHCPV6_OPT_IA_PREFIX),
+ .len = htons(sizeof(p) - 4U + ex_len),
+ .prefix = e[i].length,
+ .addr = e[i].target
+ };
+
+ memcpy(ia_pd + ia_pd_len, &p, sizeof(p));
+ ia_pd_len += sizeof(p);
+
+ if (ex_len) {
+ ia_pd[ia_pd_len++] = 0;
+ ia_pd[ia_pd_len++] = DHCPV6_OPT_PD_EXCLUDE;
+ ia_pd[ia_pd_len++] = 0;
+ ia_pd[ia_pd_len++] = ex_len - 4;
+ ia_pd[ia_pd_len++] = e[i].priority;
+
+ uint32_t excl = ntohl(e[i].router.s6_addr32[1]);
+ excl >>= (64 - e[i].priority);
+ excl <<= 8 - ((e[i].priority - e[i].length) % 8);
+
+ for (size_t i = ex_len - 5; i > 0; --i, excl >>= 8)
+ ia_pd[ia_pd_len + i] = excl & 0xff;
+ ia_pd_len += ex_len - 5;
+ }
+ }
+