DHCP6_OPTION_INTERFACE_ID = 18,
DHCP6_OPTION_RECONF_MSG = 19,
DHCP6_OPTION_RECONF_ACCEPT = 20,
+
+ DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */
+ DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */
+
+ DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075 */
+
+ /* option code 35 is unassigned */
+
+ DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */
+
+ /* option codes 89-142 are unassigned */
+ /* option codes 144-65535 are unassigned */
};
enum {
be32_t transaction_id;
struct sd_dhcp6_lease *lease;
int fd;
+ be16_t *req_opts;
+ size_t req_opts_allocated;
+ size_t req_opts_len;
sd_event_source *receive_message;
usec_t retransmit_time;
uint8_t retransmit_count;
} _packed_ duid;
};
+static const uint16_t default_req_opts[] = {
+ DHCP6_OPTION_DNS_SERVERS,
+ DHCP6_OPTION_DOMAIN_LIST,
+ DHCP6_OPTION_NTP_SERVER,
+};
+
const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = {
[DHCP6_SOLICIT] = "SOLICIT",
[DHCP6_ADVERTISE] = "ADVERTISE",
return 0;
}
+int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
+ uint16_t option) {
+ size_t t;
+
+ assert_return(client, -EINVAL);
+ assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+
+ switch(option) {
+ case DHCP6_OPTION_DNS_SERVERS:
+ case DHCP6_OPTION_DOMAIN_LIST:
+ case DHCP6_OPTION_SNTP_SERVERS:
+ case DHCP6_OPTION_NTP_SERVER:
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ for (t = 0; t < client->req_opts_len; t++)
+ if (client->req_opts[t] == htobe16(option))
+ return -EEXIST;
+
+ if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
+ client->req_opts_len + 1))
+ return -ENOMEM;
+
+ client->req_opts[client->req_opts_len++] = htobe16(option);
+
+ return 0;
+}
+
int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
assert_return(client, -EINVAL);
assert_return(ret, -EINVAL);
return -EINVAL;
}
+ r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ORO,
+ client->req_opts_len * sizeof(be16_t),
+ client->req_opts);
+ if (r < 0)
+ return r;
+
r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
sizeof(client->duid), &client->duid);
if (r < 0)
sd_dhcp6_client_detach_event(client);
+ free(client->req_opts);
free(client);
return NULL;
_cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
sd_id128_t machine_id;
int r;
+ size_t t;
assert_return(ret, -EINVAL);
siphash24(client->duid.id, &machine_id, sizeof(machine_id),
HASH_KEY.bytes);
+ client->req_opts_len = ELEMENTSOF(default_req_opts);
+
+ client->req_opts = new0(be16_t, client->req_opts_len);
+ if (!client->req_opts)
+ return -ENOMEM;
+
+ for (t = 0; t < client->req_opts_len; t++)
+ client->req_opts[t] = htobe16(default_req_opts[t]);
+
*ret = client;
client = NULL;
assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
+ 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_DOMAIN_LIST) == -EEXIST);
+ assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
+
assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
assert_se(sd_dhcp6_client_detach_event(client) >= 0);
assert_se(e);
assert_se(event == DHCP6_EVENT_IP_ACQUIRE);
+ assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
+
if (verbose)
printf(" got DHCPv6 event %d\n", event);