mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
Merge pull request #924 from pfl/systemd-dhcp6
sd-dhcpv6: support DNS and NTP information
This commit is contained in:
commit
6b8b67e7ae
@ -5,7 +5,7 @@
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
Copyright (C) 2014-2015 Intel Corporation. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
@ -68,6 +68,11 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
size_t *optlen, uint8_t **optvalue);
|
||||
int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
|
||||
DHCP6IA *ia);
|
||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count,
|
||||
size_t *allocated);
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr);
|
||||
|
||||
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
|
||||
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
||||
|
@ -6,7 +6,7 @@
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 Tom Gundersen
|
||||
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
Copyright (C) 2014-2015 Intel Corporation. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
@ -40,6 +40,17 @@ struct sd_dhcp6_lease {
|
||||
DHCP6IA ia;
|
||||
|
||||
DHCP6Address *addr_iter;
|
||||
|
||||
struct in6_addr *dns;
|
||||
size_t dns_count;
|
||||
size_t dns_allocated;
|
||||
char **domains;
|
||||
size_t domains_count;
|
||||
struct in6_addr *ntp;
|
||||
size_t ntp_count;
|
||||
size_t ntp_allocated;
|
||||
char **ntp_fqdn;
|
||||
size_t ntp_fqdn_count;
|
||||
};
|
||||
|
||||
int dhcp6_lease_clear_timers(DHCP6IA *ia);
|
||||
@ -56,6 +67,13 @@ int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit);
|
||||
|
||||
int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
|
||||
|
||||
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);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_lease*, sd_dhcp6_lease_unref);
|
||||
|
@ -3,7 +3,7 @@
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
Copyright (C) 2014-2015 Intel Corporation. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
@ -26,9 +26,11 @@
|
||||
#include "sparse-endian.h"
|
||||
#include "unaligned.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
|
||||
#include "dhcp6-internal.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
#include "dns-domain.h"
|
||||
|
||||
#define DHCP6_OPTION_IA_NA_LEN 12
|
||||
#define DHCP6_OPTION_IA_TA_LEN 4
|
||||
@ -317,3 +319,101 @@ error:
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count,
|
||||
size_t *allocated) {
|
||||
|
||||
if (optlen == 0 || optlen % sizeof(struct in6_addr) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!GREEDY_REALLOC(*addrs, *allocated,
|
||||
count * sizeof(struct in6_addr) + optlen))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(*addrs + count, optval, optlen);
|
||||
|
||||
count += optlen / sizeof(struct in6_addr);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr)
|
||||
{
|
||||
size_t pos = 0, idx = 0;
|
||||
_cleanup_free_ char **names = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(optlen > 1, -ENODATA);
|
||||
assert_return(optval[optlen] == '\0', -EINVAL);
|
||||
|
||||
while (pos < optlen) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
bool first = true;
|
||||
|
||||
for (;;) {
|
||||
uint8_t c;
|
||||
|
||||
c = optval[pos++];
|
||||
|
||||
if (c == 0)
|
||||
/* End of name */
|
||||
break;
|
||||
else if (c <= 63) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
const char *label;
|
||||
|
||||
/* Literal label */
|
||||
label = (const char *)&optval[pos];
|
||||
pos += c;
|
||||
if (pos > optlen)
|
||||
return -EMSGSIZE;
|
||||
|
||||
r = dns_label_escape(label, c, &t);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (!GREEDY_REALLOC0(ret, allocated, n + !first + strlen(t) + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
ret[n++] = '.';
|
||||
else
|
||||
first = false;
|
||||
|
||||
memcpy(ret + n, t, r);
|
||||
n += r;
|
||||
continue;
|
||||
} else {
|
||||
r = -EBADMSG;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
|
||||
r = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret[n] = 0;
|
||||
|
||||
r = strv_extend(&names, ret);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
ret = NULL;
|
||||
idx++;
|
||||
}
|
||||
|
||||
*str_arr = names;
|
||||
names = NULL;
|
||||
|
||||
return idx;
|
||||
|
||||
fail:
|
||||
return r;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
@ -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,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "conf-parser.h"
|
||||
#include "condition.h"
|
||||
#include "network-internal.h"
|
||||
#include "sd-icmp6-nd.h"
|
||||
|
||||
const char *net_get_name(struct udev_device *device) {
|
||||
const char *name, *field;
|
||||
@ -384,6 +385,20 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) {
|
||||
return size;
|
||||
}
|
||||
|
||||
void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
|
||||
size_t size) {
|
||||
unsigned i;
|
||||
|
||||
assert(f);
|
||||
assert(addresses);
|
||||
assert(size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
fprintf(f, SD_ICMP6_ADDRESS_FORMAT_STR"%s",
|
||||
SD_ICMP6_ADDRESS_FORMAT_VAL(addresses[i]),
|
||||
(i < (size - 1)) ? " ": "");
|
||||
}
|
||||
|
||||
int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
|
||||
_cleanup_free_ struct in6_addr *addresses = NULL;
|
||||
int size = 0;
|
||||
|
@ -67,6 +67,8 @@ const char *net_get_name(struct udev_device *device);
|
||||
|
||||
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
|
||||
int deserialize_in_addrs(struct in_addr **addresses, const char *string);
|
||||
void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
|
||||
size_t size);
|
||||
int deserialize_in6_addrs(struct in6_addr **addresses, const char *string);
|
||||
|
||||
/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */
|
||||
|
@ -3,7 +3,7 @@
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
Copyright (C) 2014-2015 Intel Corporation. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
@ -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] = {
|
||||
@ -272,6 +273,11 @@ static void client_notify(sd_dhcp6_client *client, int event) {
|
||||
static int client_reset(sd_dhcp6_client *client) {
|
||||
assert_return(client, -EINVAL);
|
||||
|
||||
if (client->lease) {
|
||||
dhcp6_lease_clear_timers(&client->lease->ia);
|
||||
client->lease = sd_dhcp6_lease_unref(client->lease);
|
||||
}
|
||||
|
||||
client->receive_message =
|
||||
sd_event_source_unref(client->receive_message);
|
||||
|
||||
@ -748,7 +754,36 @@ static int client_parse_message(sd_dhcp6_client *client,
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_DNS_SERVERS:
|
||||
r = dhcp6_lease_set_dns(lease, optval, optlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_DOMAIN_LIST:
|
||||
r = dhcp6_lease_set_domains(lease, optval, optlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_NTP_SERVER:
|
||||
r = dhcp6_lease_set_ntp(lease, optval, optlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_SNTP_SERVERS:
|
||||
r = dhcp6_lease_set_sntp(lease, optval, optlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (r == -ENOMSG)
|
||||
@ -802,10 +837,8 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
|
||||
client->lease = sd_dhcp6_lease_unref(client->lease);
|
||||
}
|
||||
|
||||
if (client->state != DHCP6_STATE_INFORMATION_REQUEST) {
|
||||
client->lease = lease;
|
||||
lease = NULL;
|
||||
}
|
||||
client->lease = lease;
|
||||
lease = NULL;
|
||||
|
||||
return DHCP6_STATE_BOUND;
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 Tom Gundersen
|
||||
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
Copyright (C) 2014-2015 Intel Corporation. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
@ -20,9 +22,11 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "dhcp6-lease-internal.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
|
||||
int dhcp6_lease_clear_timers(DHCP6IA *ia) {
|
||||
assert_return(ia, -EINVAL);
|
||||
@ -173,6 +177,189 @@ void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) {
|
||||
lease->addr_iter = lease->ia.addresses;
|
||||
}
|
||||
|
||||
int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
|
||||
int r;
|
||||
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(optval, -EINVAL);
|
||||
|
||||
if (!optlen)
|
||||
return 0;
|
||||
|
||||
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->dns,
|
||||
lease->dns_count,
|
||||
&lease->dns_allocated);
|
||||
if (r < 0) {
|
||||
log_dhcp6_client(client, "Invalid DNS server option: %s",
|
||||
strerror(-r));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
lease->dns_count = r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, struct in6_addr **addrs) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addrs, -EINVAL);
|
||||
|
||||
if (lease->dns_count) {
|
||||
*addrs = lease->dns;
|
||||
return lease->dns_count;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
|
||||
size_t optlen) {
|
||||
int r;
|
||||
char **domains;
|
||||
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(optval, -EINVAL);
|
||||
|
||||
if (!optlen)
|
||||
return 0;
|
||||
|
||||
r = dhcp6_option_parse_domainname(optval, optlen, &domains);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
free(lease->domains);
|
||||
lease->domains = domains;
|
||||
lease->domains_count = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(domains, -EINVAL);
|
||||
|
||||
if (lease->domains_count) {
|
||||
*domains = lease->domains;
|
||||
return lease->domains_count;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen)
|
||||
{
|
||||
int r;
|
||||
uint16_t subopt;
|
||||
size_t sublen;
|
||||
uint8_t *subval;
|
||||
|
||||
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;
|
||||
char **servers;
|
||||
|
||||
switch(subopt) {
|
||||
case DHCP6_NTP_SUBOPTION_SRV_ADDR:
|
||||
case DHCP6_NTP_SUBOPTION_MC_ADDR:
|
||||
if (sublen != 16)
|
||||
return 0;
|
||||
|
||||
s = dhcp6_option_parse_ip6addrs(subval, sublen,
|
||||
&lease->ntp,
|
||||
lease->ntp_count,
|
||||
&lease->ntp_allocated);
|
||||
if (s < 0)
|
||||
return s;
|
||||
|
||||
lease->ntp_count = s;
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_NTP_SUBOPTION_SRV_FQDN:
|
||||
r = dhcp6_option_parse_domainname(subval, sublen,
|
||||
&servers);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
|
||||
lease->ntp_fqdn = servers;
|
||||
lease->ntp_fqdn_count = r;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != -ENOMSG)
|
||||
return r;
|
||||
|
||||
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);
|
||||
assert_return(addrs, -EINVAL);
|
||||
|
||||
if (lease->ntp_count) {
|
||||
*addrs = lease->ntp;
|
||||
return lease->ntp_count;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(ntp_fqdn, -EINVAL);
|
||||
|
||||
if (lease->ntp_fqdn_count) {
|
||||
*ntp_fqdn = lease->ntp_fqdn;
|
||||
return lease->ntp_fqdn_count;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
|
||||
if (lease)
|
||||
assert_se(REFCNT_INC(lease->n_ref) >= 2);
|
||||
@ -185,6 +372,13 @@ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
|
||||
free(lease->serverid);
|
||||
dhcp6_lease_free_ia(&lease->ia);
|
||||
|
||||
free(lease->dns);
|
||||
|
||||
lease->domains = strv_free(lease->domains);
|
||||
|
||||
free(lease->ntp);
|
||||
|
||||
lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
|
||||
free(lease);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
@ -216,6 +216,8 @@ static int test_advertise_option(sd_event *e) {
|
||||
uint32_t lt_pref, lt_valid;
|
||||
int r;
|
||||
bool opt_clientid = false;
|
||||
struct in6_addr *addrs;
|
||||
char **domains;
|
||||
|
||||
if (verbose)
|
||||
printf("* %s\n", __FUNCTION__);
|
||||
@ -276,6 +278,24 @@ static int test_advertise_option(sd_event *e) {
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_DNS_SERVERS:
|
||||
assert_se(optlen == 16);
|
||||
assert_se(dhcp6_lease_set_dns(lease, optval,
|
||||
optlen) >= 0);
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_DOMAIN_LIST:
|
||||
assert_se(optlen == 11);
|
||||
assert_se(dhcp6_lease_set_domains(lease, optval,
|
||||
optlen) >= 0);
|
||||
break;
|
||||
|
||||
case DHCP6_OPTION_SNTP_SERVERS:
|
||||
assert_se(optlen == 16);
|
||||
assert_se(dhcp6_lease_set_sntp(lease, optval,
|
||||
optlen) >= 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -315,6 +335,19 @@ static int test_advertise_option(sd_event *e) {
|
||||
assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
|
||||
assert_se(preference == 0);
|
||||
|
||||
r = sd_dhcp6_lease_get_dns(lease, &addrs);
|
||||
assert_se(r == 1);
|
||||
assert_se(!memcmp(addrs, &msg_advertise[124], r * 16));
|
||||
|
||||
r = sd_dhcp6_lease_get_domains(lease, &domains);
|
||||
assert_se(r == 1);
|
||||
assert_se(!strcmp("lab.intra", domains[0]));
|
||||
assert_se(domains[1] == NULL);
|
||||
|
||||
r = sd_dhcp6_lease_get_ntp_addrs(lease, &addrs);
|
||||
assert_se(r == 1);
|
||||
assert_se(!memcmp(addrs, &msg_advertise[159], r * 16));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -339,10 +372,25 @@ int detect_virtualization(const char **id) {
|
||||
static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
|
||||
void *userdata) {
|
||||
sd_event *e = userdata;
|
||||
sd_dhcp6_lease *lease;
|
||||
struct in6_addr *addrs;
|
||||
char **domains;
|
||||
|
||||
assert_se(e);
|
||||
assert_se(event == DHCP6_EVENT_IP_ACQUIRE);
|
||||
|
||||
assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
|
||||
|
||||
assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
|
||||
assert_se(!strcmp("lab.intra", domains[0]));
|
||||
assert_se(domains[1] == NULL);
|
||||
|
||||
assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
|
||||
assert_se(!memcmp(addrs, &msg_advertise[124], 16));
|
||||
|
||||
assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
|
||||
assert_se(!memcmp(addrs, &msg_advertise[159], 16));
|
||||
|
||||
assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
|
||||
|
||||
if (verbose)
|
||||
@ -524,10 +572,25 @@ static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option,
|
||||
static void test_client_information_cb(sd_dhcp6_client *client, int event,
|
||||
void *userdata) {
|
||||
sd_event *e = userdata;
|
||||
sd_dhcp6_lease *lease;
|
||||
struct in6_addr *addrs;
|
||||
char **domains;
|
||||
|
||||
assert_se(e);
|
||||
assert_se(event == DHCP6_EVENT_INFORMATION_REQUEST);
|
||||
|
||||
assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
|
||||
|
||||
assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
|
||||
assert_se(!strcmp("lab.intra", domains[0]));
|
||||
assert_se(domains[1] == NULL);
|
||||
|
||||
assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
|
||||
assert_se(!memcmp(addrs, &msg_advertise[124], 16));
|
||||
|
||||
assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
|
||||
assert_se(!memcmp(addrs, &msg_advertise[159], 16));
|
||||
|
||||
if (verbose)
|
||||
printf(" got DHCPv6 event %d\n", event);
|
||||
|
||||
|
@ -2240,6 +2240,14 @@ int link_save(Link *link) {
|
||||
if (link->network) {
|
||||
char **address, **domain;
|
||||
bool space;
|
||||
sd_dhcp6_lease *dhcp6_lease = NULL;
|
||||
|
||||
if (link->dhcp6_client) {
|
||||
r = sd_dhcp6_client_get_lease(link->dhcp6_client,
|
||||
&dhcp6_lease);
|
||||
if (r < 0)
|
||||
log_link_debug(link, "No DHCPv6 lease");
|
||||
}
|
||||
|
||||
fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
|
||||
|
||||
@ -2261,6 +2269,19 @@ int link_save(Link *link) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (link->network->dhcp_dns && dhcp6_lease) {
|
||||
struct in6_addr *in6_addrs;
|
||||
|
||||
r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
|
||||
if (r > 0) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
serialize_in6_addrs(f, in6_addrs, r);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2284,6 +2305,32 @@ int link_save(Link *link) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (link->network->dhcp_ntp && dhcp6_lease) {
|
||||
struct in6_addr *in6_addrs;
|
||||
char **hosts;
|
||||
char **hostname;
|
||||
|
||||
r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
|
||||
&in6_addrs);
|
||||
if (r > 0) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
serialize_in6_addrs(f, in6_addrs, r);
|
||||
space = true;
|
||||
}
|
||||
|
||||
r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
|
||||
if (r > 0) {
|
||||
STRV_FOREACH(hostname, hosts) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
fputs(*hostname, f);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2307,6 +2354,21 @@ int link_save(Link *link) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
fputs(domainname, f);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (link->network->dhcp_domains && dhcp6_lease) {
|
||||
char **domains;
|
||||
|
||||
r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
|
||||
if (r >= 0) {
|
||||
STRV_FOREACH(domain, domains) {
|
||||
if (space)
|
||||
fputc(' ', f);
|
||||
fputs(*domain, f);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2014 Tom Gundersen
|
||||
Copyright (C) 2014 Intel Corporation. All rights reserved.
|
||||
Copyright (C) 2014-2015 Intel Corporation. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
@ -33,6 +33,12 @@ int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease,
|
||||
uint32_t *lifetime_preferred,
|
||||
uint32_t *lifetime_valid);
|
||||
|
||||
int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, struct in6_addr **addrs);
|
||||
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains);
|
||||
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease,
|
||||
struct in6_addr **addrs);
|
||||
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn);
|
||||
|
||||
sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease);
|
||||
sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user