]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: add SIP server address support
authorhaxibami <me@haxibami.net>
Tue, 22 Jul 2025 07:31:52 +0000 (16:31 +0900)
committerhaxibami <me@haxibami.net>
Tue, 22 Jul 2025 07:31:52 +0000 (16:31 +0900)
src/libsystemd-network/dhcp6-lease-internal.h
src/libsystemd-network/sd-dhcp6-lease.c
src/libsystemd-network/test-dhcp6-client.c
src/systemd/sd-dhcp6-lease.h

index ac7fb588eff63e856437e37ad77fa695a02eddf5..95a0049d307a15d21169454dc18d01729d2dcce4 100644 (file)
@@ -43,6 +43,8 @@ struct sd_dhcp6_lease {
         char **ntp_fqdn;
         struct in6_addr *sntp;
         size_t sntp_count;
+        struct in6_addr *sip;
+        size_t sip_count;
         char *fqdn;
         char *captive_portal;
         struct sd_dhcp6_option **sorted_vendor_options;
@@ -62,6 +64,7 @@ int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t opt
 int dhcp6_lease_add_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
 int dhcp6_lease_add_ntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
 int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
+int dhcp6_lease_add_sip_addrs(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
 int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
 int dhcp6_lease_set_captive_portal(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
 
index 4d8df252c87d6d315a2f6859f7c08b61c2b8d089..b26573f3e0a522dd04f5329e8305020841b1f881 100644 (file)
@@ -629,6 +629,28 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) {
         return strv_length(lease->ntp_fqdn);
 }
 
+int dhcp6_lease_add_sip_addrs(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
+        assert(lease);
+        assert(optval || optlen == 0);
+
+        if (optlen == 0)
+                return 0;
+
+        return dhcp6_option_parse_addresses(optval, optlen, &lease->sip, &lease->sip_count);
+}
+
+int sd_dhcp6_lease_get_sip_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
+        assert_return(lease, -EINVAL);
+
+        if (lease->sip) {
+                if (ret)
+                        *ret = lease->sip;
+                return lease->sip_count;
+        }
+
+        return -ENODATA;
+}
+
 int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
         char *fqdn;
         int r;
@@ -930,6 +952,13 @@ static int dhcp6_lease_parse_message(
 
                         break;
 
+                case SD_DHCP6_OPTION_SIP_SERVER_ADDRESS:
+                        r = dhcp6_lease_add_sip_addrs(lease, optval, optlen);
+                        if (r < 0)
+                                log_dhcp6_client_errno(client, r, "Failed to parse SIP server address option, ignoring: %m");
+
+                        break;
+
                 case SD_DHCP6_OPTION_CAPTIVE_PORTAL:
                         r = dhcp6_lease_set_captive_portal(lease, optval, optlen);
                         if (r < 0)
@@ -1020,6 +1049,7 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
         free(lease->ntp);
         strv_free(lease->ntp_fqdn);
         free(lease->sntp);
+        free(lease->sip);
 
         return mfree(lease);
 }
index 0775209e021c59822880e7c060db4c952969e7dd..34b9eb86d1cf5b6082c474e8d83d21967b3d3069 100644 (file)
         0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05
 #define NTP2_BYTES                                                      \
         0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
+#define SIP1_BYTES                                                      \
+        0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
+#define SIP2_BYTES                                                      \
+        0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
 #define CLIENT_ID_BYTES                                                 \
         0x00, 0x02, 0x00, 0x00, 0xab, 0x11, 0x61, 0x77, 0x40, 0xde, 0x13, 0x42, 0xc3, 0xa2
 #define SERVER_ID_BYTES                                                 \
@@ -67,6 +71,8 @@ static const struct in6_addr sntp1 = { { { SNTP1_BYTES } } };
 static const struct in6_addr sntp2 = { { { SNTP2_BYTES } } };
 static const struct in6_addr ntp1 = { { { NTP1_BYTES } } };
 static const struct in6_addr ntp2 = { { { NTP2_BYTES } } };
+static const struct in6_addr sip1 = { { { SIP1_BYTES } } };
+static const struct in6_addr sip2 = { { { SIP2_BYTES } } };
 static const uint8_t client_id[] = { CLIENT_ID_BYTES };
 static const uint8_t server_id[] = { SERVER_ID_BYTES };
 static uint8_t vendor_suboption_data[] = { VENDOR_SUBOPTION_BYTES };
@@ -107,6 +113,7 @@ TEST(client_basic) {
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) >= 0);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVER) >= 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS) >= 0);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_VENDOR_OPTS) >= 0);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN) >= 0);
         assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
@@ -737,6 +744,10 @@ static const uint8_t msg_reply[] = {
         /* NTP server (fqdn suboption) */
         0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
         0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
+        /* SIP server addresses */
+        0x00, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS, 0x00, 0x20,
+        SIP1_BYTES,
+        SIP2_BYTES,
         /* Domain list */
         0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
         0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
@@ -819,6 +830,10 @@ static const uint8_t msg_advertise[] = {
         /* NTP server (fqdn suboption) */
         0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
         0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
+        /* SIP server addresses */
+        0x00, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS, 0x00, 0x20,
+        SIP1_BYTES,
+        SIP2_BYTES,
         /* Domain list */
         0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
         0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
@@ -899,6 +914,10 @@ static void test_lease_common(sd_dhcp6_client *client) {
         assert_se(streq(strv[0], "ntp.intra"));
         assert_se(!strv[1]);
 
+        assert_se(sd_dhcp6_lease_get_sip_addrs(lease, &addrs) == 2);
+        assert_se(in6_addr_equal(&addrs[0], &sip1));
+        assert_se(in6_addr_equal(&addrs[1], &sip2));
+
         assert_se(lease->sntp_count == 2);
         assert_se(in6_addr_equal(&lease->sntp[0], &sntp1));
         assert_se(in6_addr_equal(&lease->sntp[1], &sntp2));
index 766adf3121b70c075d6b91b2a66c091f6625e276..340744c97b446bc49ded0bdd437924b06f5e95ee 100644 (file)
@@ -77,6 +77,7 @@ int sd_dhcp6_lease_get_dnr(sd_dhcp6_lease *lease, sd_dns_resolver **ret);
 int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret);
 int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret);
 int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret);
+int sd_dhcp6_lease_get_sip_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret);
 int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **ret);
 int sd_dhcp6_lease_get_captive_portal(sd_dhcp6_lease *lease, const char **ret);
 int sd_dhcp6_lease_get_vendor_options(sd_dhcp6_lease *lease, sd_dhcp6_option ***ret);