chiark / gitweb /
test-dhcp6-client: Add a simple Information Request test case
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Wed, 10 Dec 2014 14:17:33 +0000 (16:17 +0200)
committerTom Gundersen <teg@jklm.no>
Wed, 10 Dec 2014 17:31:21 +0000 (18:31 +0100)
Start the DHCPv6 test case by sending an Information Request, verifying
the reply and continuing at once with the normal address acquisition
procedure. Reuse the DHCPv6 Solicit Reply so that the client code is
verified to ignore any erroneously added IPv6 address information.

src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/test-dhcp6-client.c

index 940a606..017371e 100644 (file)
@@ -1025,6 +1025,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
         assert_return(client->index > 0, -EINVAL);
         assert_return(client->state != state, -EINVAL);
 
+        log_dhcp6_client(client, "client state %d new state %d", client->state, state);
         client->timeout_resend_expire =
                 sd_event_source_unref(client->timeout_resend_expire);
         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
index 26b28a2..7590839 100644 (file)
@@ -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, &lt_pref,
+                                                   &lt_valid) == -ENOMSG);
+
+        assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
+                                                  &lt_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,