sd-dhcp6-client.c revision f12abb48fc510b8b349c05e35ba048134debaf25
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering This file is part of systemd.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Copyright (C) 2014 Intel Corporation. All rights reserved.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering systemd is free software; you can redistribute it and/or modify it
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering under the terms of the GNU Lesser General Public License as published by
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering (at your option) any later version.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering systemd is distributed in the hope that it will be useful, but
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Lesser General Public License for more details.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering You should have received a copy of the GNU Lesser General Public License
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(interface_index >= -1, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek const struct ether_addr *mac_addr)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcpy(&client->mac_addr, mac_addr, sizeof(client->mac_addr));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memset(&client->mac_addr, 0x00, sizeof(client->mac_addr));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic sd_dhcp6_client *client_notify(sd_dhcp6_client *client, int event) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->cb(client, event, client->userdata);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic int client_initialize(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_event_source_unref(client->ia_na.timeout_t1);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sd_event_source_unref(client->ia_na.timeout_t2);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic sd_dhcp6_client *client_stop(sd_dhcp6_client *client, int error) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic int client_ensure_iaid(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* not in a container, udev will be around */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_udev_device_unref_ struct udev_device *device;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering char ifindex_str[2 + DECIMAL_STR_MAX(int)];
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sprintf(ifindex_str, "n%d", client->index);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering device = udev_device_new_from_device_id(udev, ifindex_str);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (udev_device_get_is_initialized(device) <= 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* not yet ready */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
b9c488f60050248b35640f28e4d00958702ba1c3Eelco Dolstra /* fall back to mac address if no predictable name available */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering siphash24((uint8_t*)&id, &client->mac_addr, ETH_ALEN,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* fold into 32 bits */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->ia_na.id = (id & 0xffffffff) ^ (id >> 32);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic int client_start(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client->index > 0, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_stop(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_start(sd_dhcp6_client *client)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_return(client->index > 0, -EINVAL);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->event = sd_event_unref(client->event);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringsd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringsd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert_se(REFCNT_INC(client->n_ref) >= 2);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringsd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (client && REFCNT_DEC(client->n_ref) <= 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#define _cleanup_dhcp6_client_free_ _cleanup_(sd_dhcp6_client_unrefp)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint sd_dhcp6_client_new(sd_dhcp6_client **ret)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_dhcp6_client_free_ sd_dhcp6_client *client = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* initialize DUID */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering client->duid.type = htobe16(DHCP6_DUID_EN);
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek client->duid.pen = htobe32(SYSTEMD_PEN);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* a bit of snake-oil perhaps, but no need to expose the machine-id