Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : /***
3 : : Copyright © 2014 Intel Corporation. All rights reserved.
4 : : ***/
5 : :
6 : : #include <net/ethernet.h>
7 : : #include <net/if_arp.h>
8 : : #include <stdbool.h>
9 : : #include <stdio.h>
10 : : #include <sys/socket.h>
11 : : #include <sys/types.h>
12 : : #include <unistd.h>
13 : :
14 : : #include "sd-dhcp6-client.h"
15 : : #include "sd-event.h"
16 : :
17 : : #include "dhcp6-internal.h"
18 : : #include "dhcp6-lease-internal.h"
19 : : #include "dhcp6-protocol.h"
20 : : #include "fd-util.h"
21 : : #include "macro.h"
22 : : #include "memory-util.h"
23 : : #include "socket-util.h"
24 : : #include "tests.h"
25 : : #include "time-util.h"
26 : : #include "virt.h"
27 : :
28 : : static struct ether_addr mac_addr = {
29 : : .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
30 : : };
31 : :
32 : : static sd_event_source *hangcheck;
33 : : static int test_dhcp_fd[2];
34 : : static int test_index = 42;
35 : : static int test_client_message_num;
36 : : static be32_t test_iaid = 0;
37 : : static uint8_t test_duid[14] = { };
38 : :
39 : 4 : static int test_client_basic(sd_event *e) {
40 : : sd_dhcp6_client *client;
41 : : int v;
42 : :
43 [ + - ]: 4 : log_debug("/* %s */", __func__);
44 : :
45 [ - + ]: 4 : assert_se(sd_dhcp6_client_new(&client) >= 0);
46 [ - + ]: 4 : assert_se(client);
47 : :
48 [ - + ]: 4 : assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
49 : :
50 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0);
51 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL);
52 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_ifindex(client, -1) == 0);
53 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0);
54 : :
55 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
56 : : sizeof (mac_addr),
57 : : ARPHRD_ETHER) >= 0);
58 : :
59 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_fqdn(client, "host") == 1);
60 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_fqdn(client, "host.domain") == 1);
61 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_fqdn(client, NULL) == 1);
62 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL);
63 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL);
64 : :
65 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL);
66 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
67 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST);
68 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST);
69 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
70 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
71 : :
72 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0);
73 : 4 : v = 0;
74 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
75 [ - + ]: 4 : assert_se(v);
76 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_information_request(client, 0) >= 0);
77 : 4 : v = 42;
78 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0);
79 [ - + ]: 4 : assert_se(v == 0);
80 : :
81 : 4 : v = 0;
82 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
83 [ - + ]: 4 : assert_se(v);
84 : 4 : v = 0;
85 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
86 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
87 [ - + ]: 4 : assert_se(v);
88 : 4 : v = 42;
89 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
90 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
91 [ - + ]: 4 : assert_se(v);
92 : :
93 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0);
94 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_prefix_delegation(client, 1) >= 0);
95 : 4 : v = 0;
96 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0);
97 [ - + ]: 4 : assert_se(v);
98 : 4 : v = 0;
99 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_prefix_delegation(client, &v) >= 0);
100 [ - + ]: 4 : assert_se(v);
101 : :
102 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
103 : :
104 [ - + ]: 4 : assert_se(sd_dhcp6_client_detach_event(client) >= 0);
105 [ - + ]: 4 : assert_se(!sd_dhcp6_client_unref(client));
106 : :
107 : 4 : return 0;
108 : : }
109 : :
110 : 4 : static int test_option(sd_event *e) {
111 : 4 : uint8_t packet[] = {
112 : : 'F', 'O', 'O',
113 : : 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x07,
114 : : 'A', 'B', 'C', 'D', 'E', 'F', 'G',
115 : : 0x00, SD_DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
116 : : '1', '2', '3', '4', '5', '6', '7', '8', '9',
117 : : 'B', 'A', 'R',
118 : : };
119 : 4 : uint8_t result[] = {
120 : : 'F', 'O', 'O',
121 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 : : 'B', 'A', 'R',
125 : : };
126 : : uint16_t optcode;
127 : : size_t optlen;
128 : : uint8_t *optval, *buf, *out;
129 : 4 : size_t zero = 0, pos = 3;
130 : 4 : size_t buflen = sizeof(packet), outlen = sizeof(result);
131 : :
132 [ + - ]: 4 : log_debug("/* %s */", __func__);
133 : :
134 [ - + ]: 4 : assert_se(buflen == outlen);
135 : :
136 [ - + ]: 4 : assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
137 : : &optval) == -ENOMSG);
138 : :
139 : 4 : buflen -= 3;
140 : 4 : buf = &packet[3];
141 : 4 : outlen -= 3;
142 : 4 : out = &result[3];
143 : :
144 [ - + ]: 4 : assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
145 : : &optval) >= 0);
146 : 4 : pos += 4 + optlen;
147 [ - + ]: 4 : assert_se(buf == &packet[pos]);
148 [ - + ]: 4 : assert_se(optcode == SD_DHCP6_OPTION_ORO);
149 [ - + ]: 4 : assert_se(optlen == 7);
150 [ - + ]: 4 : assert_se(buflen + pos == sizeof(packet));
151 : :
152 [ - + ]: 4 : assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
153 : : optval) >= 0);
154 [ - + ]: 4 : assert_se(out == &result[pos]);
155 [ - + ]: 4 : assert_se(*out == 0x00);
156 : :
157 [ - + ]: 4 : assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
158 : : &optval) >= 0);
159 : 4 : pos += 4 + optlen;
160 [ - + ]: 4 : assert_se(buf == &packet[pos]);
161 [ - + ]: 4 : assert_se(optcode == SD_DHCP6_OPTION_VENDOR_CLASS);
162 [ - + ]: 4 : assert_se(optlen == 9);
163 [ - + ]: 4 : assert_se(buflen + pos == sizeof(packet));
164 : :
165 [ - + ]: 4 : assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
166 : : optval) >= 0);
167 [ - + ]: 4 : assert_se(out == &result[pos]);
168 [ - + ]: 4 : assert_se(*out == 'B');
169 : :
170 [ - + ]: 4 : assert_se(memcmp(packet, result, sizeof(packet)) == 0);
171 : :
172 : 4 : return 0;
173 : : }
174 : :
175 : 4 : static int test_option_status(sd_event *e) {
176 : 4 : uint8_t option1[] = {
177 : : /* IA NA */
178 : : 0x00, 0x03, 0x00, 0x12, 0x1a, 0x1d, 0x1a, 0x1d,
179 : : 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
180 : : /* status option */
181 : : 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
182 : : };
183 : : static const uint8_t option2[] = {
184 : : /* IA NA */
185 : : 0x00, 0x03, 0x00, 0x2e, 0x1a, 0x1d, 0x1a, 0x1d,
186 : : 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
187 : : /* IA Addr */
188 : : 0x00, 0x05, 0x00, 0x1e,
189 : : 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
190 : : 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
191 : : 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
192 : : /* status option */
193 : : 0x00, 0x0d, 0x00, 0x02, 0x00, 0x01,
194 : : };
195 : : static const uint8_t option3[] = {
196 : : /* IA NA */
197 : : 0x00, 0x03, 0x00, 0x34, 0x1a, 0x1d, 0x1a, 0x1d,
198 : : 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
199 : : /* IA Addr */
200 : : 0x00, 0x05, 0x00, 0x24,
201 : : 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
202 : : 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
203 : : 0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d,
204 : : /* status option */
205 : : 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 'f', 'o',
206 : : 'o', 'b', 'a', 'r',
207 : : };
208 : : static const uint8_t option4[] = {
209 : : /* IA PD */
210 : : 0x00, 0x19, 0x00, 0x2f, 0x1a, 0x1d, 0x1a, 0x1d,
211 : : 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
212 : : /* IA PD Prefix */
213 : : 0x00, 0x1a, 0x00, 0x1f,
214 : : 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
215 : : 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
216 : : 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 : : 0x00,
218 : : /* status option */
219 : : 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
220 : : };
221 : : static const uint8_t option5[] = {
222 : : /* IA PD */
223 : : 0x00, 0x19, 0x00, 0x52, 0x1a, 0x1d, 0x1a, 0x1d,
224 : : 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02,
225 : : /* IA PD Prefix #1 */
226 : : 0x00, 0x1a, 0x00, 0x1f,
227 : : 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
228 : : 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe,
229 : : 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 : : 0x00,
231 : : /* status option */
232 : : 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
233 : : /* IA PD Prefix #2 */
234 : : 0x00, 0x1a, 0x00, 0x1f,
235 : : 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
236 : : 0x80, 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x0l, 0xd0,
237 : : 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 : : 0x00,
239 : : 0x00, 0x0d, 0x00, 0x02, 0x00, 0x00,
240 : : };
241 : : DHCP6Option *option;
242 : : DHCP6IA ia, pd;
243 : 4 : int r = 0;
244 : :
245 [ + - ]: 4 : log_debug("/* %s */", __func__);
246 : :
247 [ + - ]: 4 : zero(ia);
248 : 4 : option = (DHCP6Option *)option1;
249 [ - + ]: 4 : assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
250 : :
251 : 4 : r = dhcp6_option_parse_ia(option, &ia);
252 [ - + ]: 4 : assert_se(r == -EINVAL);
253 [ - + ]: 4 : assert_se(ia.addresses == NULL);
254 : :
255 : 4 : option->len = htobe16(17);
256 : 4 : r = dhcp6_option_parse_ia(option, &ia);
257 [ - + ]: 4 : assert_se(r == -ENOBUFS);
258 [ - + ]: 4 : assert_se(ia.addresses == NULL);
259 : :
260 : 4 : option->len = htobe16(sizeof(DHCP6Option));
261 : 4 : r = dhcp6_option_parse_ia(option, &ia);
262 [ - + ]: 4 : assert_se(r == -ENOBUFS);
263 [ - + ]: 4 : assert_se(ia.addresses == NULL);
264 : :
265 [ + - ]: 4 : zero(ia);
266 : 4 : option = (DHCP6Option *)option2;
267 [ - + ]: 4 : assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
268 : :
269 : 4 : r = dhcp6_option_parse_ia(option, &ia);
270 [ - + ]: 4 : assert_se(r >= 0);
271 [ - + ]: 4 : assert_se(ia.addresses == NULL);
272 : :
273 [ + - ]: 4 : zero(ia);
274 : 4 : option = (DHCP6Option *)option3;
275 [ - + ]: 4 : assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
276 : :
277 : 4 : r = dhcp6_option_parse_ia(option, &ia);
278 [ - + ]: 4 : assert_se(r >= 0);
279 [ - + ]: 4 : assert_se(ia.addresses != NULL);
280 : 4 : dhcp6_lease_free_ia(&ia);
281 : :
282 [ + - ]: 4 : zero(pd);
283 : 4 : option = (DHCP6Option *)option4;
284 [ - + ]: 4 : assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
285 : :
286 : 4 : r = dhcp6_option_parse_ia(option, &pd);
287 [ - + ]: 4 : assert_se(r == 0);
288 [ - + ]: 4 : assert_se(pd.addresses != NULL);
289 [ - + ]: 4 : assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
290 [ - + ]: 4 : assert_se(memcmp(&pd.ia_pd.lifetime_t1, &option4[8], 4) == 0);
291 [ - + ]: 4 : assert_se(memcmp(&pd.ia_pd.lifetime_t2, &option4[12], 4) == 0);
292 : 4 : dhcp6_lease_free_ia(&pd);
293 : :
294 [ + - ]: 4 : zero(pd);
295 : 4 : option = (DHCP6Option *)option5;
296 [ - + ]: 4 : assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
297 : :
298 : 4 : r = dhcp6_option_parse_ia(option, &pd);
299 [ - + ]: 4 : assert_se(r == 0);
300 [ - + ]: 4 : assert_se(pd.addresses != NULL);
301 : 4 : dhcp6_lease_free_ia(&pd);
302 : :
303 : 4 : return 0;
304 : : }
305 : :
306 : : static uint8_t msg_advertise[198] = {
307 : : 0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
308 : : 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
309 : : 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
310 : : 0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
311 : : 0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
312 : : 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
313 : : 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
314 : : 0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
315 : : 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
316 : : 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
317 : : 0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
318 : : 0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
319 : : 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
320 : : 0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
321 : : 0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
322 : : 0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
323 : : 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
324 : : 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
325 : : 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
326 : : 0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
327 : : 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
328 : : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
329 : : 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
330 : : 0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
331 : : 0x53, 0x00, 0x07, 0x00, 0x01, 0x00
332 : : };
333 : :
334 : : static uint8_t msg_reply[173] = {
335 : : 0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
336 : : 0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
337 : : 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
338 : : 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
339 : : 0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
340 : : 0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
341 : : 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
342 : : 0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
343 : : 0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
344 : : 0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
345 : : 0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
346 : : 0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
347 : : 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
348 : : 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
349 : : 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
350 : : 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
351 : : 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 : : 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
353 : : 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
354 : : 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
355 : : 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
356 : : 0x00, 0x00, 0x00, 0x00, 0x01
357 : : };
358 : :
359 : : static uint8_t fqdn_wire[16] = {
360 : : 0x04, 'h', 'o', 's', 't', 0x03, 'l', 'a', 'b',
361 : : 0x05, 'i', 'n', 't', 'r', 'a', 0x00
362 : : };
363 : :
364 : 4 : static int test_advertise_option(sd_event *e) {
365 : 8 : _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
366 : 4 : DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
367 : 4 : size_t len = sizeof(msg_advertise) - sizeof(DHCP6Message), pos = 0;
368 : : be32_t val;
369 : 4 : uint8_t preference = 255;
370 : : struct in6_addr addr;
371 : : uint32_t lt_pref, lt_valid;
372 : : int r;
373 : : uint8_t *opt;
374 : 4 : bool opt_clientid = false;
375 : : struct in6_addr *addrs;
376 : : char **domains;
377 : :
378 [ + - ]: 4 : log_debug("/* %s */", __func__);
379 : :
380 [ - + ]: 4 : assert_se(len >= sizeof(DHCP6Message));
381 : :
382 [ - + ]: 4 : assert_se(dhcp6_lease_new(&lease) >= 0);
383 : :
384 [ - + ]: 4 : assert_se(advertise->type == DHCP6_ADVERTISE);
385 [ - + ]: 4 : assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
386 : : 0x0fb4e5);
387 : :
388 [ + + ]: 32 : while (pos < len) {
389 : 28 : DHCP6Option *option = (DHCP6Option *)&advertise->options[pos];
390 : 28 : const uint16_t optcode = be16toh(option->code);
391 : 28 : const uint16_t optlen = be16toh(option->len);
392 : 28 : uint8_t *optval = option->data;
393 : :
394 [ + + + + : 28 : switch(optcode) {
- + + +
- ]
395 : 4 : case SD_DHCP6_OPTION_CLIENTID:
396 [ - + ]: 4 : assert_se(optlen == 14);
397 : :
398 : 4 : opt_clientid = true;
399 : 4 : break;
400 : :
401 : 4 : case SD_DHCP6_OPTION_IA_NA:
402 [ - + ]: 4 : assert_se(optlen == 94);
403 [ - + ]: 4 : assert_se(!memcmp(optval, &msg_advertise[26], optlen));
404 : :
405 : 4 : val = htobe32(0x0ecfa37d);
406 [ - + ]: 4 : assert_se(!memcmp(optval, &val, sizeof(val)));
407 : :
408 : 4 : val = htobe32(80);
409 [ - + ]: 4 : assert_se(!memcmp(optval + 4, &val, sizeof(val)));
410 : :
411 : 4 : val = htobe32(120);
412 [ - + ]: 4 : assert_se(!memcmp(optval + 8, &val, sizeof(val)));
413 : :
414 [ - + ]: 4 : assert_se(dhcp6_option_parse_ia(option, &lease->ia) >= 0);
415 : :
416 : 4 : break;
417 : :
418 : 4 : case SD_DHCP6_OPTION_SERVERID:
419 [ - + ]: 4 : assert_se(optlen == 14);
420 [ - + ]: 4 : assert_se(!memcmp(optval, &msg_advertise[179], optlen));
421 : :
422 [ - + ]: 4 : assert_se(dhcp6_lease_set_serverid(lease, optval,
423 : : optlen) >= 0);
424 : 4 : break;
425 : :
426 : 4 : case SD_DHCP6_OPTION_PREFERENCE:
427 [ - + ]: 4 : assert_se(optlen == 1);
428 [ - + ]: 4 : assert_se(!*optval);
429 : :
430 [ - + ]: 4 : assert_se(dhcp6_lease_set_preference(lease,
431 : : *optval) >= 0);
432 : 4 : break;
433 : :
434 : 0 : case SD_DHCP6_OPTION_ELAPSED_TIME:
435 [ # # ]: 0 : assert_se(optlen == 2);
436 : :
437 : 0 : break;
438 : :
439 : 4 : case SD_DHCP6_OPTION_DNS_SERVERS:
440 [ - + ]: 4 : assert_se(optlen == 16);
441 [ - + ]: 4 : assert_se(dhcp6_lease_set_dns(lease, optval,
442 : : optlen) >= 0);
443 : 4 : break;
444 : :
445 : 4 : case SD_DHCP6_OPTION_DOMAIN_LIST:
446 [ - + ]: 4 : assert_se(optlen == 11);
447 [ - + ]: 4 : assert_se(dhcp6_lease_set_domains(lease, optval,
448 : : optlen) >= 0);
449 : 4 : break;
450 : :
451 : 4 : case SD_DHCP6_OPTION_SNTP_SERVERS:
452 [ - + ]: 4 : assert_se(optlen == 16);
453 [ - + ]: 4 : assert_se(dhcp6_lease_set_sntp(lease, optval,
454 : : optlen) >= 0);
455 : 4 : break;
456 : :
457 : 0 : default:
458 : 0 : break;
459 : : }
460 : :
461 : 28 : pos += sizeof(*option) + optlen;
462 : : }
463 : :
464 [ - + ]: 4 : assert_se(pos == len);
465 [ - + ]: 4 : assert_se(opt_clientid);
466 : :
467 : 4 : sd_dhcp6_lease_reset_address_iter(lease);
468 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
469 : : <_valid) >= 0);
470 [ - + ]: 4 : assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
471 [ - + ]: 4 : assert_se(lt_pref == 150);
472 [ - + ]: 4 : assert_se(lt_valid == 180);
473 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
474 : : <_valid) == -ENOMSG);
475 : :
476 : 4 : sd_dhcp6_lease_reset_address_iter(lease);
477 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
478 : : <_valid) >= 0);
479 [ - + ]: 4 : assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
480 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
481 : : <_valid) == -ENOMSG);
482 : 4 : sd_dhcp6_lease_reset_address_iter(lease);
483 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
484 : : <_valid) >= 0);
485 [ - + ]: 4 : assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
486 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
487 : : <_valid) == -ENOMSG);
488 : :
489 [ - + ]: 4 : assert_se(dhcp6_lease_get_serverid(lease, &opt, &len) >= 0);
490 [ - + ]: 4 : assert_se(len == 14);
491 [ - + ]: 4 : assert_se(!memcmp(opt, &msg_advertise[179], len));
492 : :
493 [ - + ]: 4 : assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
494 [ - + ]: 4 : assert_se(preference == 0);
495 : :
496 : 4 : r = sd_dhcp6_lease_get_dns(lease, &addrs);
497 [ - + ]: 4 : assert_se(r == 1);
498 [ - + ]: 4 : assert_se(!memcmp(addrs, &msg_advertise[124], r * 16));
499 : :
500 : 4 : r = sd_dhcp6_lease_get_domains(lease, &domains);
501 [ - + ]: 4 : assert_se(r == 1);
502 [ - + ]: 4 : assert_se(!strcmp("lab.intra", domains[0]));
503 [ - + ]: 4 : assert_se(domains[1] == NULL);
504 : :
505 : 4 : r = sd_dhcp6_lease_get_ntp_addrs(lease, &addrs);
506 [ - + ]: 4 : assert_se(r == 1);
507 [ - + ]: 4 : assert_se(!memcmp(addrs, &msg_advertise[159], r * 16));
508 : :
509 : 4 : return 0;
510 : : }
511 : :
512 : 0 : static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
513 : 0 : assert_not_reached("Test case should have completed in 2 seconds");
514 : :
515 : : return 0;
516 : : }
517 : :
518 : 4 : static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
519 : : void *userdata) {
520 : 4 : sd_event *e = userdata;
521 : : sd_dhcp6_lease *lease;
522 : : struct in6_addr *addrs;
523 : : char **domains;
524 : :
525 [ + - ]: 4 : log_debug("/* %s */", __func__);
526 : :
527 [ - + ]: 4 : assert_se(e);
528 [ - + ]: 4 : assert_se(event == SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE);
529 : :
530 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
531 : :
532 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
533 [ - + ]: 4 : assert_se(!strcmp("lab.intra", domains[0]));
534 [ - + ]: 4 : assert_se(domains[1] == NULL);
535 : :
536 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
537 [ - + ]: 4 : assert_se(!memcmp(addrs, &msg_advertise[124], 16));
538 : :
539 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
540 [ - + ]: 4 : assert_se(!memcmp(addrs, &msg_advertise[159], 16));
541 : :
542 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
543 : :
544 : 4 : sd_event_exit(e, 0);
545 : 4 : }
546 : :
547 : 8 : static int test_client_send_reply(DHCP6Message *request) {
548 : : DHCP6Message reply;
549 : :
550 : 8 : reply.transaction_id = request->transaction_id;
551 : 8 : reply.type = DHCP6_REPLY;
552 : :
553 : 8 : memcpy(msg_reply, &reply.transaction_id, 4);
554 : :
555 : 8 : memcpy(&msg_reply[26], test_duid, sizeof(test_duid));
556 : :
557 : 8 : memcpy(&msg_reply[44], &test_iaid, sizeof(test_iaid));
558 : :
559 [ - + ]: 8 : assert_se(write(test_dhcp_fd[1], msg_reply, sizeof(msg_reply))
560 : : == sizeof(msg_reply));
561 : :
562 : 8 : return 0;
563 : : }
564 : :
565 : 4 : static int test_client_verify_request(DHCP6Message *request, size_t len) {
566 : 8 : _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
567 : 4 : size_t pos = 0;
568 : 4 : bool found_clientid = false, found_iana = false, found_serverid = false,
569 : 4 : found_elapsed_time = false, found_fqdn = false;
570 : : struct in6_addr addr;
571 : : be32_t val;
572 : : uint32_t lt_pref, lt_valid;
573 : :
574 [ + - ]: 4 : log_debug("/* %s */", __func__);
575 : :
576 [ - + ]: 4 : assert_se(request->type == DHCP6_REQUEST);
577 [ - + ]: 4 : assert_se(dhcp6_lease_new(&lease) >= 0);
578 : :
579 : 4 : len -= sizeof(DHCP6Message);
580 : :
581 [ + + ]: 28 : while (pos < len) {
582 : 24 : DHCP6Option *option = (DHCP6Option *)&request->options[pos];
583 : 24 : uint16_t optcode = be16toh(option->code);
584 : 24 : uint16_t optlen = be16toh(option->len);
585 : 24 : uint8_t *optval = option->data;
586 : :
587 [ + + + + : 24 : switch(optcode) {
+ + ]
588 : 4 : case SD_DHCP6_OPTION_CLIENTID:
589 [ - + ]: 4 : assert_se(!found_clientid);
590 : 4 : found_clientid = true;
591 : :
592 [ - + ]: 4 : assert_se(!memcmp(optval, &test_duid,
593 : : sizeof(test_duid)));
594 : :
595 : 4 : break;
596 : :
597 : 4 : case SD_DHCP6_OPTION_IA_NA:
598 [ - + ]: 4 : assert_se(!found_iana);
599 : 4 : found_iana = true;
600 : :
601 [ - + ]: 4 : assert_se(optlen == 40);
602 [ - + ]: 4 : assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
603 : :
604 : 4 : val = htobe32(80);
605 [ - + ]: 4 : assert_se(!memcmp(optval + 4, &val, sizeof(val)));
606 : :
607 : 4 : val = htobe32(120);
608 [ - + ]: 4 : assert_se(!memcmp(optval + 8, &val, sizeof(val)));
609 : :
610 [ - + ]: 4 : assert_se(!dhcp6_option_parse_ia(option, &lease->ia));
611 : :
612 : 4 : break;
613 : :
614 : 4 : case SD_DHCP6_OPTION_SERVERID:
615 [ - + ]: 4 : assert_se(!found_serverid);
616 : 4 : found_serverid = true;
617 : :
618 [ - + ]: 4 : assert_se(optlen == 14);
619 [ - + ]: 4 : assert_se(!memcmp(&msg_advertise[179], optval, optlen));
620 : :
621 : 4 : break;
622 : :
623 : 4 : case SD_DHCP6_OPTION_ELAPSED_TIME:
624 [ - + ]: 4 : assert_se(!found_elapsed_time);
625 : 4 : found_elapsed_time = true;
626 : :
627 [ - + ]: 4 : assert_se(optlen == 2);
628 : :
629 : 4 : break;
630 : 4 : case SD_DHCP6_OPTION_FQDN:
631 [ - + ]: 4 : assert_se(!found_fqdn);
632 : 4 : found_fqdn = true;
633 : :
634 [ - + ]: 4 : assert_se(optlen == 17);
635 : :
636 [ - + ]: 4 : assert_se(optval[0] == 0x01);
637 [ - + ]: 4 : assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
638 : 4 : break;
639 : : }
640 : :
641 : 24 : pos += sizeof(*option) + optlen;
642 : : }
643 : :
644 [ + - - + : 4 : assert_se(found_clientid && found_iana && found_serverid &&
+ - - + +
- - + ]
645 : : found_elapsed_time);
646 : :
647 : 4 : sd_dhcp6_lease_reset_address_iter(lease);
648 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
649 : : <_valid) >= 0);
650 [ - + ]: 4 : assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
651 [ - + ]: 4 : assert_se(lt_pref == 150);
652 [ - + ]: 4 : assert_se(lt_valid == 180);
653 : :
654 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
655 : : <_valid) == -ENOMSG);
656 : :
657 : 4 : return 0;
658 : : }
659 : :
660 : 4 : static int test_client_send_advertise(DHCP6Message *solicit) {
661 : : DHCP6Message advertise;
662 : :
663 : 4 : advertise.transaction_id = solicit->transaction_id;
664 : 4 : advertise.type = DHCP6_ADVERTISE;
665 : :
666 : 4 : memcpy(msg_advertise, &advertise.transaction_id, 4);
667 : :
668 : 4 : memcpy(&msg_advertise[8], test_duid, sizeof(test_duid));
669 : :
670 : 4 : memcpy(&msg_advertise[26], &test_iaid, sizeof(test_iaid));
671 : :
672 [ - + ]: 4 : assert_se(write(test_dhcp_fd[1], msg_advertise, sizeof(msg_advertise))
673 : : == sizeof(msg_advertise));
674 : :
675 : 4 : return 0;
676 : : }
677 : :
678 : 4 : static int test_client_verify_solicit(DHCP6Message *solicit, size_t len) {
679 : 4 : bool found_clientid = false, found_iana = false,
680 : 4 : found_elapsed_time = false, found_fqdn = false;
681 : 4 : size_t pos = 0;
682 : :
683 [ + - ]: 4 : log_debug("/* %s */", __func__);
684 : :
685 [ - + ]: 4 : assert_se(solicit->type == DHCP6_SOLICIT);
686 : :
687 : 4 : len -= sizeof(DHCP6Message);
688 : :
689 [ + + ]: 28 : while (pos < len) {
690 : 24 : DHCP6Option *option = (DHCP6Option *)&solicit->options[pos];
691 : 24 : uint16_t optcode = be16toh(option->code);
692 : 24 : uint16_t optlen = be16toh(option->len);
693 : 24 : uint8_t *optval = option->data;
694 : :
695 [ + + + + : 24 : switch(optcode) {
+ ]
696 : 4 : case SD_DHCP6_OPTION_CLIENTID:
697 [ - + ]: 4 : assert_se(!found_clientid);
698 : 4 : found_clientid = true;
699 : :
700 [ - + ]: 4 : assert_se(optlen == sizeof(test_duid));
701 : 4 : memcpy(&test_duid, optval, sizeof(test_duid));
702 : :
703 : 4 : break;
704 : :
705 : 4 : case SD_DHCP6_OPTION_IA_NA:
706 [ - + ]: 4 : assert_se(!found_iana);
707 : 4 : found_iana = true;
708 : :
709 [ - + ]: 4 : assert_se(optlen == 12);
710 : :
711 : 4 : memcpy(&test_iaid, optval, sizeof(test_iaid));
712 : :
713 : 4 : break;
714 : :
715 : 4 : case SD_DHCP6_OPTION_ELAPSED_TIME:
716 [ - + ]: 4 : assert_se(!found_elapsed_time);
717 : 4 : found_elapsed_time = true;
718 : :
719 [ - + ]: 4 : assert_se(optlen == 2);
720 : :
721 : 4 : break;
722 : :
723 : 4 : case SD_DHCP6_OPTION_FQDN:
724 [ - + ]: 4 : assert_se(!found_fqdn);
725 : 4 : found_fqdn = true;
726 : :
727 [ - + ]: 4 : assert_se(optlen == 17);
728 : :
729 [ - + ]: 4 : assert_se(optval[0] == 0x01);
730 [ - + ]: 4 : assert_se(!memcmp(optval + 1, fqdn_wire, sizeof(fqdn_wire)));
731 : :
732 : 4 : break;
733 : : }
734 : :
735 : 24 : pos += sizeof(*option) + optlen;
736 : : }
737 : :
738 [ - + ]: 4 : assert_se(pos == len);
739 [ + - - + : 4 : assert_se(found_clientid && found_iana && found_elapsed_time);
+ - - + ]
740 : :
741 : 4 : return 0;
742 : : }
743 : :
744 : 4 : static void test_client_information_cb(sd_dhcp6_client *client, int event,
745 : : void *userdata) {
746 : 4 : sd_event *e = userdata;
747 : : sd_dhcp6_lease *lease;
748 : : struct in6_addr *addrs;
749 : 4 : struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
750 : : char **domains;
751 : :
752 [ + - ]: 4 : log_debug("/* %s */", __func__);
753 : :
754 [ - + ]: 4 : assert_se(e);
755 [ - + ]: 4 : assert_se(event == SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST);
756 : :
757 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_lease(client, &lease) >= 0);
758 : :
759 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_domains(lease, &domains) == 1);
760 [ - + ]: 4 : assert_se(!strcmp("lab.intra", domains[0]));
761 [ - + ]: 4 : assert_se(domains[1] == NULL);
762 : :
763 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_dns(lease, &addrs) == 1);
764 [ - + ]: 4 : assert_se(!memcmp(addrs, &msg_advertise[124], 16));
765 : :
766 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_ntp_addrs(lease, &addrs) == 1);
767 [ - + ]: 4 : assert_se(!memcmp(addrs, &msg_advertise[159], 16));
768 : :
769 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_information_request(client, false) == -EBUSY);
770 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_callback(client, NULL, e) >= 0);
771 [ - + ]: 4 : assert_se(sd_dhcp6_client_stop(client) >= 0);
772 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0);
773 : :
774 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_callback(client,
775 : : test_client_solicit_cb, e) >= 0);
776 : :
777 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
778 : :
779 [ - + ]: 4 : assert_se(sd_dhcp6_client_start(client) >= 0);
780 : :
781 : 4 : }
782 : :
783 : 4 : static int test_client_verify_information_request(DHCP6Message *information_request,
784 : : size_t len) {
785 : :
786 : 8 : _cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
787 : 4 : size_t pos = 0;
788 : 4 : bool found_clientid = false, found_elapsed_time = false;
789 : : struct in6_addr addr;
790 : : uint32_t lt_pref, lt_valid;
791 : :
792 [ + - ]: 4 : log_debug("/* %s */", __func__);
793 : :
794 [ - + ]: 4 : assert_se(information_request->type == DHCP6_INFORMATION_REQUEST);
795 [ - + ]: 4 : assert_se(dhcp6_lease_new(&lease) >= 0);
796 : :
797 : 4 : len -= sizeof(DHCP6Message);
798 : :
799 [ + + ]: 16 : while (pos < len) {
800 : 12 : DHCP6Option *option = (DHCP6Option *)&information_request->options[pos];
801 : 12 : uint16_t optcode = be16toh(option->code);
802 : 12 : uint16_t optlen = be16toh(option->len);
803 : 12 : uint8_t *optval = option->data;
804 : :
805 [ + - - + : 12 : switch(optcode) {
+ ]
806 : 4 : case SD_DHCP6_OPTION_CLIENTID:
807 [ - + ]: 4 : assert_se(!found_clientid);
808 : 4 : found_clientid = true;
809 : :
810 [ - + ]: 4 : assert_se(optlen == sizeof(test_duid));
811 : 4 : memcpy(&test_duid, optval, sizeof(test_duid));
812 : :
813 : 4 : break;
814 : :
815 : 0 : case SD_DHCP6_OPTION_IA_NA:
816 : 0 : assert_not_reached("IA TA option must not be present");
817 : :
818 : : break;
819 : :
820 : 0 : case SD_DHCP6_OPTION_SERVERID:
821 : 0 : assert_not_reached("Server ID option must not be present");
822 : :
823 : : break;
824 : :
825 : 4 : case SD_DHCP6_OPTION_ELAPSED_TIME:
826 [ - + ]: 4 : assert_se(!found_elapsed_time);
827 : 4 : found_elapsed_time = true;
828 : :
829 [ - + ]: 4 : assert_se(optlen == 2);
830 : :
831 : 4 : break;
832 : : }
833 : :
834 : 12 : pos += sizeof(*option) + optlen;
835 : : }
836 : :
837 [ - + ]: 4 : assert_se(pos == len);
838 [ + - - + ]: 4 : assert_se(found_clientid && found_elapsed_time);
839 : :
840 : 4 : sd_dhcp6_lease_reset_address_iter(lease);
841 : :
842 [ - + ]: 4 : assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
843 : : <_valid) == -ENOMSG);
844 : :
845 : 4 : return 0;
846 : : }
847 : :
848 : 12 : int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
849 : : const void *packet, size_t len) {
850 : 12 : struct in6_addr mcast =
851 : : IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
852 : : DHCP6Message *message;
853 : :
854 [ - + ]: 12 : assert_se(s == test_dhcp_fd[0]);
855 [ - + ]: 12 : assert_se(server_address);
856 [ - + ]: 12 : assert_se(packet);
857 [ - + ]: 12 : assert_se(len > sizeof(DHCP6Message) + 4);
858 [ + - + - : 12 : assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast));
+ - + - -
+ ]
859 : :
860 : 12 : message = (DHCP6Message *)packet;
861 : :
862 [ - + ]: 12 : assert_se(message->transaction_id & 0x00ffffff);
863 : :
864 [ + + ]: 12 : if (test_client_message_num == 0) {
865 : 4 : test_client_verify_information_request(message, len);
866 : 4 : test_client_send_reply(message);
867 : 4 : test_client_message_num++;
868 [ + + ]: 8 : } else if (test_client_message_num == 1) {
869 : 4 : test_client_verify_solicit(message, len);
870 : 4 : test_client_send_advertise(message);
871 : 4 : test_client_message_num++;
872 [ + - ]: 4 : } else if (test_client_message_num == 2) {
873 : 4 : test_client_verify_request(message, len);
874 : 4 : test_client_send_reply(message);
875 : 4 : test_client_message_num++;
876 : : }
877 : :
878 : 12 : return len;
879 : : }
880 : :
881 : 8 : int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
882 [ - + ]: 8 : assert_se(index == test_index);
883 : :
884 [ - + ]: 8 : if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) < 0)
885 : 0 : return -errno;
886 : :
887 : 8 : return test_dhcp_fd[0];
888 : : }
889 : :
890 : 4 : static int test_client_solicit(sd_event *e) {
891 : : sd_dhcp6_client *client;
892 : 4 : usec_t time_now = now(clock_boottime_or_monotonic());
893 : 4 : struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
894 : : int val;
895 : :
896 [ + - ]: 4 : log_debug("/* %s */", __func__);
897 : :
898 [ - + ]: 4 : assert_se(sd_dhcp6_client_new(&client) >= 0);
899 [ - + ]: 4 : assert_se(client);
900 : :
901 [ - + ]: 4 : assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
902 : :
903 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0);
904 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
905 : : sizeof (mac_addr),
906 : : ARPHRD_ETHER) >= 0);
907 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1);
908 : :
909 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
910 [ - + ]: 4 : assert_se(val == 0);
911 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_information_request(client, 42) >= 0);
912 [ - + ]: 4 : assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
913 [ - + ]: 4 : assert_se(val);
914 : :
915 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_callback(client,
916 : : test_client_information_cb, e) >= 0);
917 : :
918 [ - + ]: 4 : assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(),
919 : : time_now + 2 * USEC_PER_SEC, 0,
920 : : test_hangcheck, NULL) >= 0);
921 : :
922 [ - + ]: 4 : assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
923 : :
924 [ - + ]: 4 : assert_se(sd_dhcp6_client_start(client) >= 0);
925 : :
926 : 4 : sd_event_loop(e);
927 : :
928 : 4 : hangcheck = sd_event_source_unref(hangcheck);
929 : :
930 [ - + ]: 4 : assert_se(!sd_dhcp6_client_unref(client));
931 : :
932 : 4 : test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
933 : :
934 : 4 : return 0;
935 : : }
936 : :
937 : 4 : int main(int argc, char *argv[]) {
938 : 4 : _cleanup_(sd_event_unrefp) sd_event *e;
939 : :
940 [ - + ]: 4 : assert_se(sd_event_new(&e) >= 0);
941 : :
942 : 4 : test_setup_logging(LOG_DEBUG);
943 : :
944 : 4 : test_client_basic(e);
945 : 4 : test_option(e);
946 : 4 : test_option_status(e);
947 : 4 : test_advertise_option(e);
948 : 4 : test_client_solicit(e);
949 : :
950 : 4 : return 0;
951 : : }
|