From 6599680e2d33597f0f11a99e1c3c957b42418568 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Fri, 10 Apr 2015 15:59:00 +0300 Subject: sd-dhcp6: Add support for DHCPv6 NTP Server Option Support NTP server and multicast addresses and NTP server domain names as specified in RFC 5908. --- src/libsystemd-network/dhcp6-protocol.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/libsystemd-network/dhcp6-protocol.h') diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h index 3e0f339237..9330f239b5 100644 --- a/src/libsystemd-network/dhcp6-protocol.h +++ b/src/libsystemd-network/dhcp6-protocol.h @@ -133,6 +133,12 @@ enum { /* option codes 144-65535 are unassigned */ }; +enum { + DHCP6_NTP_SUBOPTION_SRV_ADDR = 1, + DHCP6_NTP_SUBOPTION_MC_ADDR = 2, + DHCP6_NTP_SUBOPTION_SRV_FQDN = 3, +}; + enum { DHCP6_STATUS_SUCCESS = 0, DHCP6_STATUS_UNSPEC_FAIL = 1, -- cgit v1.2.3-54-g00ecf From 41e4615d4f4f5c61afa84ba857f23c0ac496687b Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Fri, 10 Apr 2015 16:17:22 +0300 Subject: sd-dhcp6: Support deprecated SNTP Configuration Option Although the SNTP option specified in RFC 4075 has been deprecated, some servers are still sending NTP information with this option. Use the SNTP information provided only if the NTP option is not present. Update the test case as SNTP information is also requested. --- src/libsystemd-network/dhcp6-lease-internal.h | 2 ++ src/libsystemd-network/dhcp6-protocol.h | 2 +- src/libsystemd-network/sd-dhcp6-client.c | 8 ++++++ src/libsystemd-network/sd-dhcp6-lease.c | 36 +++++++++++++++++++++++++++ src/libsystemd-network/test-dhcp6-client.c | 2 +- 5 files changed, 48 insertions(+), 2 deletions(-) (limited to 'src/libsystemd-network/dhcp6-protocol.h') diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index ac7f84366d..037f580eb6 100644 --- a/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libsystemd-network/dhcp6-lease-internal.h @@ -71,6 +71,8 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen); int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen); int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen); +int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, + size_t optlen) ; int dhcp6_lease_new(sd_dhcp6_lease **ret); diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h index 9330f239b5..b3a28f88b4 100644 --- a/src/libsystemd-network/dhcp6-protocol.h +++ b/src/libsystemd-network/dhcp6-protocol.h @@ -123,7 +123,7 @@ enum { DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */ DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */ - DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075 */ + DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */ /* option code 35 is unassigned */ diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 986958d8ad..bc17c6adc5 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -73,6 +73,7 @@ static const uint16_t default_req_opts[] = { DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_NTP_SERVER, + DHCP6_OPTION_SNTP_SERVERS, }; const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = { @@ -774,6 +775,13 @@ static int client_parse_message(sd_dhcp6_client *client, return r; break; + + case DHCP6_OPTION_SNTP_SERVERS: + r = dhcp6_lease_set_sntp(lease, optval, optlen); + if (r < 0) + return r; + + break; } } diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 8631aabc40..f0494b3c91 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -257,6 +257,10 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) assert_return(lease, -EINVAL); assert_return(optval, -EINVAL); + free(lease->ntp); + lease->ntp_count = 0; + lease->ntp_allocated = 0; + while ((r = dhcp6_option_parse(&optval, &optlen, &subopt, &sublen, &subval)) >= 0) { int s; @@ -299,6 +303,38 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) return 0; } +int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) { + int r; + + assert_return(lease, -EINVAL); + assert_return(optval, -EINVAL); + + if (!optlen) + return 0; + + if (lease->ntp || lease->ntp_fqdn) { + log_dhcp6_client(client, "NTP information already provided"); + + return 0; + } + + log_dhcp6_client(client, "Using deprecated SNTP information"); + + r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp, + lease->ntp_count, + &lease->ntp_allocated); + if (r < 0) { + log_dhcp6_client(client, "Invalid SNTP server option: %s", + strerror(-r)); + + return r; + } + + lease->ntp_count = r; + + return 0; +} + int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, struct in6_addr **addrs) { assert_return(lease, -EINVAL); diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 761854714b..b61fd38ade 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -73,7 +73,7 @@ static int test_client_basic(sd_event *e) { assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_CLIENTID) == -EINVAL); assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_NTP_SERVER) == -EEXIST); - assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_SNTP_SERVERS) == 0); + assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_SNTP_SERVERS) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DOMAIN_LIST) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL); -- cgit v1.2.3-54-g00ecf