+/* Parse NTP Options for DHCPv6 Address */
+static int parse_ntp_options(uint16_t *dhcpv6_ntp_len, struct in6_addr addr6, uint8_t **dhcpv6_ntp)
+{
+ uint16_t sub_opt = 0, sub_len = htons(IPV6_ADDR_LEN);
+ uint16_t ntp_len = IPV6_ADDR_LEN + 4;
+ uint8_t *ntp = *dhcpv6_ntp;
+ size_t pos = *dhcpv6_ntp_len;
+
+ ntp = realloc(ntp, pos + ntp_len);
+ if (!ntp)
+ return -1;
+
+ *dhcpv6_ntp = ntp;
+
+ if (IN6_IS_ADDR_MULTICAST(&addr6))
+ sub_opt = htons(NTP_SUBOPTION_MC_ADDR);
+ else
+ sub_opt = htons(NTP_SUBOPTION_SRV_ADDR);
+
+ memcpy(ntp + pos, &sub_opt, sizeof(sub_opt));
+ pos += sizeof(sub_opt);
+ memcpy(ntp + pos, &sub_len, sizeof(sub_len));
+ pos += sizeof(sub_len);
+ memcpy(ntp + pos, &addr6, IPV6_ADDR_LEN);
+
+ *dhcpv6_ntp_len += ntp_len;
+
+ return 0;
+}
+
+/* Parse NTP Options for FQDN */
+static int parse_ntp_fqdn(uint16_t *dhcpv6_ntp_len, char *fqdn, uint8_t **dhcpv6_ntp)
+{
+ size_t fqdn_len = strlen(fqdn);
+ uint16_t sub_opt = 0, sub_len = 0, ntp_len = 0;
+ uint8_t *ntp = *dhcpv6_ntp;
+ size_t pos = *dhcpv6_ntp_len;
+ uint8_t buf[256] = {0};
+
+ if (fqdn_len > 0 && fqdn[fqdn_len - 1] == '.')
+ fqdn[fqdn_len - 1] = 0;
+
+ int len = dn_comp(fqdn, buf, sizeof(buf), NULL, NULL);
+ if (len <= 0)
+ return -1;
+
+ ntp_len = len + 4;
+
+ ntp = realloc(ntp, pos + ntp_len);
+ if (!ntp)
+ return -1;
+
+ *dhcpv6_ntp = ntp;
+
+ sub_opt = htons(NTP_SUBOPTION_SRV_FQDN);
+ sub_len = htons(len);
+
+ memcpy(ntp + pos, &sub_opt, sizeof(sub_opt));
+ pos += sizeof(sub_opt);
+ memcpy(ntp + pos, &sub_len, sizeof(sub_len));
+ pos += sizeof(sub_len);
+ memcpy(ntp + pos, buf, len);
+
+ *dhcpv6_ntp_len += ntp_len;
+
+ return 0;
+}
+