2 This file is part of systemd.
4 Copyright (C) 2014 Intel Corporation. All rights reserved.
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include <net/ethernet.h>
23 #include <sys/socket.h>
24 #include <sys/types.h>
27 #include "sd-dhcp6-client.h"
30 #include "dhcp6-internal.h"
31 #include "dhcp6-lease-internal.h"
32 #include "dhcp6-protocol.h"
35 #include "socket-util.h"
38 static struct ether_addr mac_addr
= {
39 .ether_addr_octet
= {'A', 'B', 'C', '1', '2', '3'}
42 static bool verbose
= true;
44 static sd_event_source
*hangcheck
;
45 static int test_dhcp_fd
[2];
46 static int test_index
= 42;
47 static int test_client_message_num
;
48 static be32_t test_iaid
= 0;
49 static uint8_t test_duid
[14] = { };
51 static int test_client_basic(sd_event
*e
) {
52 sd_dhcp6_client
*client
;
55 printf("* %s\n", __FUNCTION__
);
57 assert_se(sd_dhcp6_client_new(&client
) >= 0);
60 assert_se(sd_dhcp6_client_attach_event(client
, e
, 0) >= 0);
62 assert_se(sd_dhcp6_client_set_ifindex(client
, 15) == 0);
63 assert_se(sd_dhcp6_client_set_ifindex(client
, -42) == -EINVAL
);
64 assert_se(sd_dhcp6_client_set_ifindex(client
, -1) == 0);
65 assert_se(sd_dhcp6_client_set_ifindex(client
, 42) >= 0);
67 assert_se(sd_dhcp6_client_set_mac(client
, (const uint8_t *) &mac_addr
,
71 assert_se(sd_dhcp6_client_set_request_option(client
, SD_DHCP6_OPTION_CLIENTID
) == -EINVAL
);
72 assert_se(sd_dhcp6_client_set_request_option(client
, SD_DHCP6_OPTION_DNS_SERVERS
) == -EEXIST
);
73 assert_se(sd_dhcp6_client_set_request_option(client
, SD_DHCP6_OPTION_NTP_SERVER
) == -EEXIST
);
74 assert_se(sd_dhcp6_client_set_request_option(client
, SD_DHCP6_OPTION_SNTP_SERVERS
) == -EEXIST
);
75 assert_se(sd_dhcp6_client_set_request_option(client
, SD_DHCP6_OPTION_DOMAIN_LIST
) == -EEXIST
);
76 assert_se(sd_dhcp6_client_set_request_option(client
, 10) == -EINVAL
);
78 assert_se(sd_dhcp6_client_set_callback(client
, NULL
, NULL
) >= 0);
80 assert_se(sd_dhcp6_client_detach_event(client
) >= 0);
81 assert_se(!sd_dhcp6_client_unref(client
));
86 static int test_option(sd_event
*e
) {
89 0x00, SD_DHCP6_OPTION_ORO
, 0x00, 0x07,
90 'A', 'B', 'C', 'D', 'E', 'F', 'G',
91 0x00, SD_DHCP6_OPTION_VENDOR_CLASS
, 0x00, 0x09,
92 '1', '2', '3', '4', '5', '6', '7', '8', '9',
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 uint8_t *optval
, *buf
, *out
;
105 size_t zero
= 0, pos
= 3;
106 size_t buflen
= sizeof(packet
), outlen
= sizeof(result
);
109 printf("* %s\n", __FUNCTION__
);
111 assert_se(buflen
== outlen
);
113 assert_se(dhcp6_option_parse(&buf
, &zero
, &optcode
, &optlen
,
114 &optval
) == -ENOMSG
);
121 assert_se(dhcp6_option_parse(&buf
, &buflen
, &optcode
, &optlen
,
124 assert_se(buf
== &packet
[pos
]);
125 assert_se(optcode
== SD_DHCP6_OPTION_ORO
);
126 assert_se(optlen
== 7);
127 assert_se(buflen
+ pos
== sizeof(packet
));
129 assert_se(dhcp6_option_append(&out
, &outlen
, optcode
, optlen
,
131 assert_se(out
== &result
[pos
]);
132 assert_se(*out
== 0x00);
134 assert_se(dhcp6_option_parse(&buf
, &buflen
, &optcode
, &optlen
,
137 assert_se(buf
== &packet
[pos
]);
138 assert_se(optcode
== SD_DHCP6_OPTION_VENDOR_CLASS
);
139 assert_se(optlen
== 9);
140 assert_se(buflen
+ pos
== sizeof(packet
));
142 assert_se(dhcp6_option_append(&out
, &outlen
, optcode
, optlen
,
144 assert_se(out
== &result
[pos
]);
145 assert_se(*out
== 'B');
147 assert_se(memcmp(packet
, result
, sizeof(packet
)) == 0);
152 static uint8_t msg_advertise
[198] = {
153 0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
154 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
155 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
156 0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
157 0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
158 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
159 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
160 0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
161 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
162 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
163 0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
164 0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
165 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
166 0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
167 0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
168 0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
169 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
171 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
172 0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
173 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
175 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
176 0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
177 0x53, 0x00, 0x07, 0x00, 0x01, 0x00
180 static uint8_t msg_reply
[173] = {
181 0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
182 0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
183 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
184 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
185 0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
186 0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
187 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
188 0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
189 0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
190 0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
191 0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
192 0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
193 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
194 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
195 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
196 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
197 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
199 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
200 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
201 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x01
205 static int test_advertise_option(sd_event
*e
) {
206 _cleanup_(sd_dhcp6_lease_unrefp
) sd_dhcp6_lease
*lease
= NULL
;
207 DHCP6Message
*advertise
= (DHCP6Message
*)msg_advertise
;
208 uint8_t *optval
, *opt
= msg_advertise
+ sizeof(DHCP6Message
);
210 size_t optlen
, len
= sizeof(msg_advertise
) - sizeof(DHCP6Message
);
212 uint8_t preference
= 255;
213 struct in6_addr addr
;
214 uint32_t lt_pref
, lt_valid
;
216 bool opt_clientid
= false;
217 struct in6_addr
*addrs
;
221 printf("* %s\n", __FUNCTION__
);
223 assert_se(dhcp6_lease_new(&lease
) >= 0);
225 assert_se(advertise
->type
== DHCP6_ADVERTISE
);
226 assert_se((be32toh(advertise
->transaction_id
) & 0x00ffffff) ==
229 while ((r
= dhcp6_option_parse(&opt
, &len
, &optcode
, &optlen
,
233 case SD_DHCP6_OPTION_CLIENTID
:
234 assert_se(optlen
== 14);
239 case SD_DHCP6_OPTION_IA_NA
:
240 assert_se(optlen
== 94);
241 assert_se(!memcmp(optval
, &msg_advertise
[26], optlen
));
243 val
= htobe32(0x0ecfa37d);
244 assert_se(!memcmp(optval
, &val
, sizeof(val
)));
247 assert_se(!memcmp(optval
+ 4, &val
, sizeof(val
)));
250 assert_se(!memcmp(optval
+ 8, &val
, sizeof(val
)));
252 assert_se(dhcp6_option_parse_ia(&optval
, &optlen
,
258 case SD_DHCP6_OPTION_SERVERID
:
259 assert_se(optlen
== 14);
260 assert_se(!memcmp(optval
, &msg_advertise
[179], optlen
));
262 assert_se(dhcp6_lease_set_serverid(lease
, optval
,
266 case SD_DHCP6_OPTION_PREFERENCE
:
267 assert_se(optlen
== 1);
270 assert_se(dhcp6_lease_set_preference(lease
,
274 case SD_DHCP6_OPTION_ELAPSED_TIME
:
275 assert_se(optlen
== 2);
279 case SD_DHCP6_OPTION_DNS_SERVERS
:
280 assert_se(optlen
== 16);
281 assert_se(dhcp6_lease_set_dns(lease
, optval
,
285 case SD_DHCP6_OPTION_DOMAIN_LIST
:
286 assert_se(optlen
== 11);
287 assert_se(dhcp6_lease_set_domains(lease
, optval
,
291 case SD_DHCP6_OPTION_SNTP_SERVERS
:
292 assert_se(optlen
== 16);
293 assert_se(dhcp6_lease_set_sntp(lease
, optval
,
303 assert_se(r
== -ENOMSG
);
305 assert_se(opt_clientid
);
307 sd_dhcp6_lease_reset_address_iter(lease
);
308 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
310 assert_se(!memcmp(&addr
, &msg_advertise
[42], sizeof(addr
)));
311 assert_se(lt_pref
== 150);
312 assert_se(lt_valid
== 180);
313 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
314 <_valid
) == -ENOMSG
);
316 sd_dhcp6_lease_reset_address_iter(lease
);
317 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
319 assert_se(!memcmp(&addr
, &msg_advertise
[42], sizeof(addr
)));
320 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
321 <_valid
) == -ENOMSG
);
322 sd_dhcp6_lease_reset_address_iter(lease
);
323 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
325 assert_se(!memcmp(&addr
, &msg_advertise
[42], sizeof(addr
)));
326 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
327 <_valid
) == -ENOMSG
);
329 assert_se(dhcp6_lease_get_serverid(lease
, &opt
, &len
) >= 0);
330 assert_se(len
== 14);
331 assert_se(!memcmp(opt
, &msg_advertise
[179], len
));
333 assert_se(dhcp6_lease_get_preference(lease
, &preference
) >= 0);
334 assert_se(preference
== 0);
336 r
= sd_dhcp6_lease_get_dns(lease
, &addrs
);
338 assert_se(!memcmp(addrs
, &msg_advertise
[124], r
* 16));
340 r
= sd_dhcp6_lease_get_domains(lease
, &domains
);
342 assert_se(!strcmp("lab.intra", domains
[0]));
343 assert_se(domains
[1] == NULL
);
345 r
= sd_dhcp6_lease_get_ntp_addrs(lease
, &addrs
);
347 assert_se(!memcmp(addrs
, &msg_advertise
[159], r
* 16));
352 static int test_hangcheck(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
353 assert_not_reached("Test case should have completed in 2 seconds");
358 static void test_client_solicit_cb(sd_dhcp6_client
*client
, int event
,
360 sd_event
*e
= userdata
;
361 sd_dhcp6_lease
*lease
;
362 struct in6_addr
*addrs
;
366 assert_se(event
== SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE
);
368 assert_se(sd_dhcp6_client_get_lease(client
, &lease
) >= 0);
370 assert_se(sd_dhcp6_lease_get_domains(lease
, &domains
) == 1);
371 assert_se(!strcmp("lab.intra", domains
[0]));
372 assert_se(domains
[1] == NULL
);
374 assert_se(sd_dhcp6_lease_get_dns(lease
, &addrs
) == 1);
375 assert_se(!memcmp(addrs
, &msg_advertise
[124], 16));
377 assert_se(sd_dhcp6_lease_get_ntp_addrs(lease
, &addrs
) == 1);
378 assert_se(!memcmp(addrs
, &msg_advertise
[159], 16));
380 assert_se(sd_dhcp6_client_set_request_option(client
, SD_DHCP6_OPTION_DNS_SERVERS
) == -EBUSY
);
383 printf(" got DHCPv6 event %d\n", event
);
388 static int test_client_send_reply(DHCP6Message
*request
) {
391 reply
.transaction_id
= request
->transaction_id
;
392 reply
.type
= DHCP6_REPLY
;
394 memcpy(msg_reply
, &reply
.transaction_id
, 4);
396 memcpy(&msg_reply
[26], test_duid
, sizeof(test_duid
));
398 memcpy(&msg_reply
[44], &test_iaid
, sizeof(test_iaid
));
400 assert_se(write(test_dhcp_fd
[1], msg_reply
, sizeof(msg_reply
))
401 == sizeof(msg_reply
));
406 static int test_client_verify_request(DHCP6Message
*request
, uint8_t *option
,
408 _cleanup_(sd_dhcp6_lease_unrefp
) sd_dhcp6_lease
*lease
= NULL
;
412 bool found_clientid
= false, found_iana
= false, found_serverid
= false,
413 found_elapsed_time
= false;
415 struct in6_addr addr
;
417 uint32_t lt_pref
, lt_valid
;
419 assert_se(request
->type
== DHCP6_REQUEST
);
421 assert_se(dhcp6_lease_new(&lease
) >= 0);
423 while ((r
= dhcp6_option_parse(&option
, &len
,
424 &optcode
, &optlen
, &optval
)) >= 0) {
426 case SD_DHCP6_OPTION_CLIENTID
:
427 assert_se(!found_clientid
);
428 found_clientid
= true;
430 assert_se(!memcmp(optval
, &test_duid
,
435 case SD_DHCP6_OPTION_IA_NA
:
436 assert_se(!found_iana
);
440 assert_se(optlen
== 40);
441 assert_se(!memcmp(optval
, &test_iaid
, sizeof(test_iaid
)));
444 assert_se(!memcmp(optval
+ 4, &val
, sizeof(val
)));
447 assert_se(!memcmp(optval
+ 8, &val
, sizeof(val
)));
449 assert_se(!dhcp6_option_parse_ia(&optval
, &optlen
,
450 optcode
, &lease
->ia
));
454 case SD_DHCP6_OPTION_SERVERID
:
455 assert_se(!found_serverid
);
456 found_serverid
= true;
458 assert_se(optlen
== 14);
459 assert_se(!memcmp(&msg_advertise
[179], optval
, optlen
));
463 case SD_DHCP6_OPTION_ELAPSED_TIME
:
464 assert_se(!found_elapsed_time
);
465 found_elapsed_time
= true;
467 assert_se(optlen
== 2);
473 assert_se(r
== -ENOMSG
);
474 assert_se(found_clientid
&& found_iana
&& found_serverid
&&
477 sd_dhcp6_lease_reset_address_iter(lease
);
478 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
480 assert_se(!memcmp(&addr
, &msg_advertise
[42], sizeof(addr
)));
481 assert_se(lt_pref
== 150);
482 assert_se(lt_valid
== 180);
484 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
485 <_valid
) == -ENOMSG
);
490 static int test_client_send_advertise(DHCP6Message
*solicit
) {
491 DHCP6Message advertise
;
493 advertise
.transaction_id
= solicit
->transaction_id
;
494 advertise
.type
= DHCP6_ADVERTISE
;
496 memcpy(msg_advertise
, &advertise
.transaction_id
, 4);
498 memcpy(&msg_advertise
[8], test_duid
, sizeof(test_duid
));
500 memcpy(&msg_advertise
[26], &test_iaid
, sizeof(test_iaid
));
502 assert_se(write(test_dhcp_fd
[1], msg_advertise
, sizeof(msg_advertise
))
503 == sizeof(msg_advertise
));
508 static int test_client_verify_solicit(DHCP6Message
*solicit
, uint8_t *option
,
513 bool found_clientid
= false, found_iana
= false,
514 found_elapsed_time
= false;
517 assert_se(solicit
->type
== DHCP6_SOLICIT
);
519 while ((r
= dhcp6_option_parse(&option
, &len
,
520 &optcode
, &optlen
, &optval
)) >= 0) {
522 case SD_DHCP6_OPTION_CLIENTID
:
523 assert_se(!found_clientid
);
524 found_clientid
= true;
526 assert_se(optlen
== sizeof(test_duid
));
527 memcpy(&test_duid
, optval
, sizeof(test_duid
));
531 case SD_DHCP6_OPTION_IA_NA
:
532 assert_se(!found_iana
);
535 assert_se(optlen
== 12);
537 memcpy(&test_iaid
, optval
, sizeof(test_iaid
));
541 case SD_DHCP6_OPTION_ELAPSED_TIME
:
542 assert_se(!found_elapsed_time
);
543 found_elapsed_time
= true;
545 assert_se(optlen
== 2);
551 assert_se(r
== -ENOMSG
);
552 assert_se(found_clientid
&& found_iana
&& found_elapsed_time
);
557 static void test_client_information_cb(sd_dhcp6_client
*client
, int event
,
559 sd_event
*e
= userdata
;
560 sd_dhcp6_lease
*lease
;
561 struct in6_addr
*addrs
;
562 struct in6_addr address
= { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
566 assert_se(event
== SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST
);
568 assert_se(sd_dhcp6_client_get_lease(client
, &lease
) >= 0);
570 assert_se(sd_dhcp6_lease_get_domains(lease
, &domains
) == 1);
571 assert_se(!strcmp("lab.intra", domains
[0]));
572 assert_se(domains
[1] == NULL
);
574 assert_se(sd_dhcp6_lease_get_dns(lease
, &addrs
) == 1);
575 assert_se(!memcmp(addrs
, &msg_advertise
[124], 16));
577 assert_se(sd_dhcp6_lease_get_ntp_addrs(lease
, &addrs
) == 1);
578 assert_se(!memcmp(addrs
, &msg_advertise
[159], 16));
581 printf(" got DHCPv6 event %d\n", event
);
583 assert_se(sd_dhcp6_client_set_information_request(client
, false) == -EBUSY
);
584 assert_se(sd_dhcp6_client_set_callback(client
, NULL
, e
) >= 0);
585 assert_se(sd_dhcp6_client_stop(client
) >= 0);
586 assert_se(sd_dhcp6_client_set_information_request(client
, false) >= 0);
588 assert_se(sd_dhcp6_client_set_callback(client
,
589 test_client_solicit_cb
, e
) >= 0);
591 assert_se(sd_dhcp6_client_set_local_address(client
, &address
) >= 0);
593 assert_se(sd_dhcp6_client_start(client
) >= 0);
596 static int test_client_verify_information_request(DHCP6Message
*information_request
,
597 uint8_t *option
, size_t len
) {
599 _cleanup_(sd_dhcp6_lease_unrefp
) sd_dhcp6_lease
*lease
= NULL
;
603 bool found_clientid
= false, found_elapsed_time
= false;
605 struct in6_addr addr
;
606 uint32_t lt_pref
, lt_valid
;
608 assert_se(information_request
->type
== DHCP6_INFORMATION_REQUEST
);
610 assert_se(dhcp6_lease_new(&lease
) >= 0);
612 while ((r
= dhcp6_option_parse(&option
, &len
,
613 &optcode
, &optlen
, &optval
)) >= 0) {
615 case SD_DHCP6_OPTION_CLIENTID
:
616 assert_se(!found_clientid
);
617 found_clientid
= true;
619 assert_se(optlen
== sizeof(test_duid
));
620 memcpy(&test_duid
, optval
, sizeof(test_duid
));
624 case SD_DHCP6_OPTION_IA_NA
:
625 assert_not_reached("IA TA option must not be present");
629 case SD_DHCP6_OPTION_SERVERID
:
630 assert_not_reached("Server ID option must not be present");
634 case SD_DHCP6_OPTION_ELAPSED_TIME
:
635 assert_se(!found_elapsed_time
);
636 found_elapsed_time
= true;
638 assert_se(optlen
== 2);
644 assert_se(r
== -ENOMSG
);
645 assert_se(found_clientid
&& found_elapsed_time
);
647 sd_dhcp6_lease_reset_address_iter(lease
);
649 assert_se(sd_dhcp6_lease_get_address(lease
, &addr
, <_pref
,
650 <_valid
) == -ENOMSG
);
655 int dhcp6_network_send_udp_socket(int s
, struct in6_addr
*server_address
,
656 const void *packet
, size_t len
) {
657 struct in6_addr mcast
=
658 IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT
;
659 DHCP6Message
*message
;
662 assert_se(s
== test_dhcp_fd
[0]);
663 assert_se(server_address
);
665 assert_se(len
> sizeof(DHCP6Message
) + 4);
667 assert_se(IN6_ARE_ADDR_EQUAL(server_address
, &mcast
));
669 message
= (DHCP6Message
*)packet
;
670 option
= (uint8_t *)(message
+ 1);
671 len
-= sizeof(DHCP6Message
);
673 assert_se(message
->transaction_id
& 0x00ffffff);
675 if (test_client_message_num
== 0) {
676 test_client_verify_information_request(message
, option
, len
);
677 test_client_send_reply(message
);
678 test_client_message_num
++;
679 } else if (test_client_message_num
== 1) {
680 test_client_verify_solicit(message
, option
, len
);
681 test_client_send_advertise(message
);
682 test_client_message_num
++;
683 } else if (test_client_message_num
== 2) {
684 test_client_verify_request(message
, option
, len
);
685 test_client_send_reply(message
);
686 test_client_message_num
++;
692 int dhcp6_network_bind_udp_socket(int index
, struct in6_addr
*local_address
) {
693 assert_se(index
== test_index
);
695 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, test_dhcp_fd
) < 0)
698 return test_dhcp_fd
[0];
701 static int test_client_solicit(sd_event
*e
) {
702 sd_dhcp6_client
*client
;
703 usec_t time_now
= now(clock_boottime_or_monotonic());
704 struct in6_addr address
= { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
708 printf("* %s\n", __FUNCTION__
);
710 assert_se(sd_dhcp6_client_new(&client
) >= 0);
713 assert_se(sd_dhcp6_client_attach_event(client
, e
, 0) >= 0);
715 assert_se(sd_dhcp6_client_set_ifindex(client
, test_index
) == 0);
716 assert_se(sd_dhcp6_client_set_mac(client
, (const uint8_t *) &mac_addr
,
720 assert_se(sd_dhcp6_client_get_information_request(client
, &val
) >= 0);
721 assert_se(val
== false);
722 assert_se(sd_dhcp6_client_set_information_request(client
, true) >= 0);
723 assert_se(sd_dhcp6_client_get_information_request(client
, &val
) >= 0);
724 assert_se(val
== true);
726 assert_se(sd_dhcp6_client_set_callback(client
,
727 test_client_information_cb
, e
) >= 0);
729 assert_se(sd_event_add_time(e
, &hangcheck
, clock_boottime_or_monotonic(),
730 time_now
+ 2 * USEC_PER_SEC
, 0,
731 test_hangcheck
, NULL
) >= 0);
733 assert_se(sd_dhcp6_client_set_local_address(client
, &address
) >= 0);
735 assert_se(sd_dhcp6_client_start(client
) >= 0);
739 hangcheck
= sd_event_source_unref(hangcheck
);
741 assert_se(!sd_dhcp6_client_unref(client
));
743 test_dhcp_fd
[1] = safe_close(test_dhcp_fd
[1]);
748 int main(int argc
, char *argv
[]) {
749 _cleanup_(sd_event_unrefp
) sd_event
*e
;
751 assert_se(sd_event_new(&e
) >= 0);
753 log_set_max_level(LOG_DEBUG
);
754 log_parse_environment();
757 test_client_basic(e
);
759 test_advertise_option(e
);
760 test_client_solicit(e
);