X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-network%2Ftest-dhcp6-client.c;h=75908391f0c47944e4201e4d8866f9440164a191;hb=fe21f16764147d51819a904d57ac36967f9913e3;hp=37ddfc2cfaa9805974f1cd773e5cb5ec52a43c6c;hpb=d63be95a306bf1e262c7e1c7ad4b2c12b49d371e;p=elogind.git diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 37ddfc2cf..75908391f 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]; @@ -66,7 +66,9 @@ static int test_client_basic(sd_event *e) { assert_se(sd_dhcp6_client_set_index(client, -1) == 0); assert_se(sd_dhcp6_client_set_index(client, 42) >= 0); - assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0); + assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, + sizeof (mac_addr), + ARPHRD_ETHER) >= 0); assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_CLIENTID) == -EINVAL); assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EEXIST); @@ -333,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) { @@ -511,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 = @@ -532,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++; @@ -544,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__); @@ -572,10 +656,18 @@ static int test_client_solicit(sd_event *e) { assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); assert_se(sd_dhcp6_client_set_index(client, test_index) == 0); - assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0); + assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, + 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,