1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2014 Intel Corporation. All rights reserved.
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "sd-dhcp6-client.h"
29 #include "dhcp6-protocol.h"
31 struct sd_dhcp6_client {
34 enum DHCP6State state;
38 struct ether_addr mac_addr;
39 sd_dhcp6_client_cb_t cb;
43 int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
44 sd_dhcp6_client_cb_t cb, void *userdata)
46 assert_return(client, -EINVAL);
49 client->userdata = userdata;
54 int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
56 assert_return(client, -EINVAL);
57 assert_return(interface_index >= -1, -EINVAL);
59 client->index = interface_index;
64 int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
65 const struct ether_addr *mac_addr)
67 assert_return(client, -EINVAL);
70 memcpy(&client->mac_addr, mac_addr, sizeof(client->mac_addr));
72 memset(&client->mac_addr, 0x00, sizeof(client->mac_addr));
77 static sd_dhcp6_client *client_notify(sd_dhcp6_client *client, int event) {
79 client = sd_dhcp6_client_ref(client);
80 client->cb(client, event, client->userdata);
81 client = sd_dhcp6_client_unref(client);
87 static int client_initialize(sd_dhcp6_client *client)
89 assert_return(client, -EINVAL);
91 client->state = DHCP6_STATE_STOPPED;
96 static sd_dhcp6_client *client_stop(sd_dhcp6_client *client, int error) {
97 assert_return(client, NULL);
99 client = client_notify(client, error);
101 client_initialize(client);
106 int sd_dhcp6_client_stop(sd_dhcp6_client *client)
108 client_stop(client, DHCP6_EVENT_STOP);
113 int sd_dhcp6_client_start(sd_dhcp6_client *client)
117 assert_return(client, -EINVAL);
118 assert_return(client->event, -EINVAL);
119 assert_return(client->index > 0, -EINVAL);
124 int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
129 assert_return(client, -EINVAL);
130 assert_return(!client->event, -EBUSY);
133 client->event = sd_event_ref(event);
135 r = sd_event_default(&client->event);
140 client->event_priority = priority;
145 int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
146 assert_return(client, -EINVAL);
148 client->event = sd_event_unref(client->event);
153 sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
157 return client->event;
160 sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
162 assert_se(REFCNT_INC(client->n_ref) >= 2);
167 sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
168 if (client && REFCNT_DEC(client->n_ref) <= 0) {
170 client_initialize(client);
172 sd_dhcp6_client_detach_event(client);
182 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
183 #define _cleanup_dhcp6_client_free_ _cleanup_(sd_dhcp6_client_unrefp)
185 int sd_dhcp6_client_new(sd_dhcp6_client **ret)
187 _cleanup_dhcp6_client_free_ sd_dhcp6_client *client = NULL;
189 assert_return(ret, -EINVAL);
191 client = new0(sd_dhcp6_client, 1);
195 client->n_ref = REFCNT_INIT;