summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/test-dhcp6-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-network/test-dhcp6-client.c')
-rw-r--r--src/libsystemd-network/test-dhcp6-client.c82
1 files changed, 78 insertions, 4 deletions
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
index 3e1c52a306..00c11909c9 100644
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ b/src/libsystemd-network/test-dhcp6-client.c
@@ -602,6 +602,62 @@ static const uint8_t msg_request[] = {
0x00, 0x00,
};
+/* RFC 3315 section 18.1.6. The DHCP6 Release message must include:
+ - transaction id
+ - server identifier
+ - client identifier
+ - all released IA with addresses included
+ - elapsed time (required for all messages).
+ All other options aren't required. */
+static const uint8_t msg_release[] = {
+ /* Message type */
+ DHCP6_MESSAGE_RELEASE,
+ /* Transaction ID */
+ 0x00, 0x00, 0x00,
+ /* Server ID */
+ 0x00, SD_DHCP6_OPTION_SERVERID, 0x00, 0x0e,
+ SERVER_ID_BYTES,
+ /* IA_NA */
+ 0x00, SD_DHCP6_OPTION_IA_NA, 0x00, 0x44,
+ IA_ID_BYTES,
+ 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
+ 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
+ /* IA_NA (IAADDR suboption) */
+ 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
+ IA_NA_ADDRESS1_BYTES,
+ 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
+ 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
+ /* IA_NA (IAADDR suboption) */
+ 0x00, SD_DHCP6_OPTION_IAADDR, 0x00, 0x18,
+ IA_NA_ADDRESS2_BYTES,
+ 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
+ 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
+ /* IA_PD */
+ 0x00, SD_DHCP6_OPTION_IA_PD, 0x00, 0x46,
+ IA_ID_BYTES,
+ 0x00, 0x00, 0x00, 0x00, /* lifetime T1 */
+ 0x00, 0x00, 0x00, 0x00, /* lifetime T2 */
+ /* IA_PD (IA_PD_PREFIX suboption) */
+ 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
+ 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
+ 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
+ 0x40, /* prefixlen */
+ IA_PD_PREFIX1_BYTES,
+ /* IA_PD (IA_PD_PREFIX suboption) */
+ 0x00, SD_DHCP6_OPTION_IA_PD_PREFIX, 0x00, 0x19,
+ 0x00, 0x00, 0x00, 0x00, /* preferred lifetime */
+ 0x00, 0x00, 0x00, 0x00, /* valid lifetime */
+ 0x40, /* prefixlen */
+ IA_PD_PREFIX2_BYTES,
+ /* Client ID */
+ 0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
+ CLIENT_ID_BYTES,
+ /* Extra options */
+ /* Elapsed time */
+ 0x00, SD_DHCP6_OPTION_ELAPSED_TIME, 0x00, 0x02,
+ 0x00, 0x00,
+};
+
static const uint8_t msg_reply[] = {
/* Message type */
DHCP6_MESSAGE_REPLY,
@@ -775,13 +831,24 @@ static void test_client_verify_solicit(const DHCP6Message *msg, size_t len) {
assert_se(memcmp(msg, msg_solicit, len - sizeof(be16_t)) == 0);
}
+static void test_client_verify_release(const DHCP6Message *msg, size_t len) {
+ log_debug("/* %s */", __func__);
+
+ assert_se(len == sizeof(msg_release));
+ assert_se(msg->type == DHCP6_MESSAGE_RELEASE);
+ /* The transaction ID and elapsed time value are not deterministic. Skip them. */
+ assert_se(memcmp(msg->options, msg_release + offsetof(DHCP6Message, options),
+ len - offsetof(DHCP6Message, options) - sizeof(be16_t)) == 0);
+}
+
static void test_client_verify_request(const DHCP6Message *msg, size_t len) {
log_debug("/* %s */", __func__);
assert_se(len == sizeof(msg_request));
assert_se(msg->type == DHCP6_MESSAGE_REQUEST);
/* The transaction ID and elapsed time value are not deterministic. Skip them. */
- assert_se(memcmp(msg->options, msg_request + offsetof(DHCP6Message, options), len - offsetof(DHCP6Message, options) - sizeof(be16_t)) == 0);
+ assert_se(memcmp(msg->options, msg_request + offsetof(DHCP6Message, options),
+ len - offsetof(DHCP6Message, options) - sizeof(be16_t)) == 0);
}
static void test_lease_common(sd_dhcp6_client *client) {
@@ -905,7 +972,7 @@ static void test_client_callback(sd_dhcp6_client *client, int event, void *userd
case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
log_debug("/* %s (event=ip-acquire) */", __func__);
- assert_se(IN_SET(test_client_sent_message_count, 3, 4));
+ assert_se(IN_SET(test_client_sent_message_count, 3, 5));
test_lease_managed(client);
@@ -916,7 +983,7 @@ static void test_client_callback(sd_dhcp6_client *client, int event, void *userd
assert_se(dhcp6_client_set_transaction_id(client, ((const DHCP6Message*) msg_reply)->transaction_id) >= 0);
break;
- case 4:
+ case 5:
assert_se(sd_event_exit(sd_dhcp6_client_get_event(client), 0) >= 0);
break;
@@ -974,6 +1041,12 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *a, const void *packet,
break;
case 3:
+ test_client_verify_release(packet, len);
+ /* when stopping, dhcp6 client doesn't wait for release server reply */
+ assert_se(write(test_fd[1], msg_reply, sizeof(msg_reply)) == sizeof(msg_reply));
+ break;
+
+ case 4:
test_client_verify_solicit(packet, len);
assert_se(write(test_fd[1], msg_reply, sizeof(msg_reply)) == sizeof(msg_reply));
break;
@@ -1010,6 +1083,7 @@ TEST(dhcp6_client) {
assert_se(sd_dhcp6_client_set_local_address(client, &local_address) >= 0);
assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") >= 0);
assert_se(sd_dhcp6_client_set_iaid(client, unaligned_read_be32((uint8_t[]) { IA_ID_BYTES })) >= 0);
+ assert_se(sd_dhcp6_client_set_send_release(client, true) >= 0);
dhcp6_client_set_test_mode(client, true);
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0);
@@ -1028,7 +1102,7 @@ TEST(dhcp6_client) {
assert_se(sd_event_loop(e) >= 0);
- assert_se(test_client_sent_message_count == 4);
+ assert_se(test_client_sent_message_count == 5);
assert_se(!sd_dhcp6_client_unref(client_ref));
test_fd[1] = safe_close(test_fd[1]);