diff options
Diffstat (limited to 'src/libsystemd-network/test-dhcp6-client.c')
-rw-r--r-- | src/libsystemd-network/test-dhcp6-client.c | 126 |
1 files changed, 107 insertions, 19 deletions
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 26b28a20e8..75908391f0 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -41,7 +41,7 @@ static struct ether_addr mac_addr = { .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} }; -static bool verbose = false; +static bool verbose = true; static sd_event_source *hangcheck; static int test_dhcp_fd[2]; @@ -335,13 +335,19 @@ int detect_virtualization(const char **id) { return 1; } -int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { - assert_se(index == test_index); +static void test_client_solicit_cb(sd_dhcp6_client *client, int event, + void *userdata) { + sd_event *e = userdata; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0) - return -errno; + assert_se(e); + assert_se(event == DHCP6_EVENT_IP_ACQUIRE); - return test_dhcp_fd[0]; + assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY); + + if (verbose) + printf(" got DHCPv6 event %d\n", event); + + sd_event_exit(e, 0); } static int test_client_send_reply(DHCP6Message *request) { @@ -513,6 +519,83 @@ static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option, return 0; } +static void test_client_information_cb(sd_dhcp6_client *client, int event, + void *userdata) { + sd_event *e = userdata; + + assert_se(e); + assert_se(event == DHCP6_EVENT_INFORMATION_REQUEST); + + if (verbose) + printf(" got DHCPv6 event %d\n", event); + + assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0); + assert_se(sd_dhcp6_client_set_callback(client, + test_client_solicit_cb, e) >= 0); + + assert_se(sd_dhcp6_client_start(client) >= 0); +} + +static int test_client_verify_information_request(DHCP6Message *information_request, + uint8_t *option, size_t len) { + + _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; + uint8_t *optval; + uint16_t optcode; + size_t optlen; + bool found_clientid = false, found_elapsed_time = false; + int r; + struct in6_addr addr; + uint32_t lt_pref, lt_valid; + + assert_se(information_request->type == DHCP6_INFORMATION_REQUEST); + + assert_se(dhcp6_lease_new(&lease) >= 0); + + while ((r = dhcp6_option_parse(&option, &len, + &optcode, &optlen, &optval)) >= 0) { + switch(optcode) { + case DHCP6_OPTION_CLIENTID: + assert_se(!found_clientid); + found_clientid = true; + + assert_se(optlen == sizeof(test_duid)); + memcpy(&test_duid, optval, sizeof(test_duid)); + + break; + + case DHCP6_OPTION_IA_NA: + assert_not_reached("IA TA option must not be present"); + + break; + + case DHCP6_OPTION_SERVERID: + assert_not_reached("Server ID option must not be present"); + + break; + + case DHCP6_OPTION_ELAPSED_TIME: + assert_se(!found_elapsed_time); + found_elapsed_time = true; + + assert_se(optlen == 2); + + break; + } + } + + assert_se(r == -ENOMSG); + assert_se(found_clientid && found_elapsed_time); + + assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, <_pref, + <_valid) == -ENOMSG); + + assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, <_pref, + <_valid) == -ENOMSG); + + return 0; +} + int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, const void *packet, size_t len) { struct in6_addr mcast = @@ -534,10 +617,14 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, assert_se(message->transaction_id & 0x00ffffff); if (test_client_message_num == 0) { + test_client_verify_information_request(message, option, len); + test_client_send_reply(message); + test_client_message_num++; + } else if (test_client_message_num == 1) { test_client_verify_solicit(message, option, len); test_client_send_advertise(message); test_client_message_num++; - } else if (test_client_message_num == 1) { + } else if (test_client_message_num == 2) { test_client_verify_request(message, option, len); test_client_send_reply(message); test_client_message_num++; @@ -546,24 +633,19 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, return len; } -static void test_client_solicit_cb(sd_dhcp6_client *client, int event, - void *userdata) { - sd_event *e = userdata; - - assert_se(e); - assert_se(event == DHCP6_EVENT_IP_ACQUIRE); - - assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY); +int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { + assert_se(index == test_index); - if (verbose) - printf(" got DHCPv6 event %d\n", event); + if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0) + return -errno; - sd_event_exit(e, 0); + return test_dhcp_fd[0]; } static int test_client_solicit(sd_event *e) { sd_dhcp6_client *client; usec_t time_now = now(clock_boottime_or_monotonic()); + bool val = true; if (verbose) printf("* %s\n", __FUNCTION__); @@ -578,8 +660,14 @@ static int test_client_solicit(sd_event *e) { sizeof (mac_addr), ARPHRD_ETHER) >= 0); + assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0); + assert_se(val == false); + assert_se(sd_dhcp6_client_set_information_request(client, true) >= 0); + assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0); + assert_se(val == true); + assert_se(sd_dhcp6_client_set_callback(client, - test_client_solicit_cb, e) >= 0); + test_client_information_cb, e) >= 0); assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(), time_now + 2 * USEC_PER_SEC, 0, |