From e0026dcbd21b172d51ac05e476044ac9504c1f71 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Thu, 4 Jan 2018 15:11:40 +0200 Subject: [PATCH] dhcp6: Name structs in DHCP6IA Name structs containing IA NA with ID and T1 and T2 lifetimes and IA TA containing only the ID so that the structs can be expressed properly. --- src/libsystemd-network/dhcp6-internal.h | 21 +++++++++++++----- src/libsystemd-network/dhcp6-option.c | 28 ++++++++++++------------ src/libsystemd-network/sd-dhcp6-client.c | 20 ++++++++--------- src/libsystemd-network/sd-dhcp6-lease.c | 4 ++-- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h index cb5b359cbe..9bff5c2dcd 100644 --- a/src/libsystemd-network/dhcp6-internal.h +++ b/src/libsystemd-network/dhcp6-internal.h @@ -41,13 +41,24 @@ struct DHCP6Address { } iaaddr _packed_; }; +/* Non-temporary Address option */ +struct ia_na { + be32_t id; + be32_t lifetime_t1; + be32_t lifetime_t2; +} _packed_; + +/* Temporary Address option */ +struct ia_ta { + be32_t id; +} _packed_; + struct DHCP6IA { uint16_t type; - struct { - be32_t id; - be32_t lifetime_t1; - be32_t lifetime_t2; - } _packed_; + union { + struct ia_na ia_na; + struct ia_ta ia_ta; + }; sd_event_source *timeout_t1; sd_event_source *timeout_t2; diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index f346bda5fc..139b7a4c5c 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -82,6 +82,7 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { uint16_t len; + be32_t *iaid; uint8_t *ia_hdr; size_t ia_buflen, ia_addrlen = 0; DHCP6Address *addr; @@ -92,10 +93,12 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { switch (ia->type) { case SD_DHCP6_OPTION_IA_NA: len = DHCP6_OPTION_IA_NA_LEN; + iaid = &ia->ia_na.id; break; case SD_DHCP6_OPTION_IA_TA: len = DHCP6_OPTION_IA_TA_LEN; + iaid = &ia->ia_ta.id; break; default: @@ -111,7 +114,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { *buf += sizeof(DHCP6Option); *buflen -= sizeof(DHCP6Option); - memcpy(*buf, &ia->id, len); + memcpy(*buf, iaid, len); *buf += len; *buflen -= len; @@ -232,10 +235,10 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, } iaaddr_offset = DHCP6_OPTION_IA_NA_LEN; - memcpy(&ia->id, *buf, iaaddr_offset); + memcpy(&ia->ia_na, *buf, sizeof(ia->ia_na)); - lt_t1 = be32toh(ia->lifetime_t1); - lt_t2 = be32toh(ia->lifetime_t2); + lt_t1 = be32toh(ia->ia_na.lifetime_t1); + lt_t2 = be32toh(ia->ia_na.lifetime_t2); if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { log_dhcp6_client(client, "IA T1 %ds > T2 %ds", @@ -254,10 +257,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, } iaaddr_offset = DHCP6_OPTION_IA_TA_LEN; - memcpy(&ia->id, *buf, iaaddr_offset); - - ia->lifetime_t1 = 0; - ia->lifetime_t2 = 0; + memcpy(&ia->ia_ta.id, *buf, sizeof(ia->ia_ta)); break; @@ -327,19 +327,19 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, if (r == -ENOMSG) r = 0; - if (!ia->lifetime_t1 && !ia->lifetime_t2) { + if (*buflen) + r = -ENOMSG; + + if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2) { lt_t1 = lt_min / 2; lt_t2 = lt_min / 10 * 8; - ia->lifetime_t1 = htobe32(lt_t1); - ia->lifetime_t2 = htobe32(lt_t2); + ia->ia_na.lifetime_t1 = htobe32(lt_t1); + ia->ia_na.lifetime_t2 = htobe32(lt_t2); log_dhcp6_client(client, "Computed IA T1 %ds and T2 %ds as both were zero", lt_t1, lt_t2); } - if (*buflen) - r = -ENOMSG; - error: *buf += *buflen; *buflen = 0; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 074a409cbf..87f37dc0d4 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -230,7 +230,7 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) { assert_return(client, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); - client->ia_na.id = htobe32(iaid); + client->ia_na.ia_na.id = htobe32(iaid); return 0; } @@ -710,10 +710,10 @@ static int client_ensure_iaid(sd_dhcp6_client *client) { assert(client); - if (client->ia_na.id) + if (client->ia_na.ia_na.id) return 0; - r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->ia_na.id); + r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len, &client->ia_na.ia_na.id); if (r < 0) return r; @@ -815,7 +815,7 @@ static int client_parse_message( if (r < 0) return r; - if (client->ia_na.id != iaid_lease) { + if (client->ia_na.ia_na.id != iaid_lease) { log_dhcp6_client(client, "%s has wrong IAID", dhcp6_message_type_to_string(message->type)); return -EINVAL; @@ -1133,17 +1133,17 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { case DHCP6_STATE_BOUND: - if (client->lease->ia.lifetime_t1 == 0xffffffff || - client->lease->ia.lifetime_t2 == 0xffffffff) { + if (client->lease->ia.ia_na.lifetime_t1 == 0xffffffff || + client->lease->ia.ia_na.lifetime_t2 == 0xffffffff) { log_dhcp6_client(client, "Infinite T1 0x%08x or T2 0x%08x", - be32toh(client->lease->ia.lifetime_t1), - be32toh(client->lease->ia.lifetime_t2)); + be32toh(client->lease->ia.ia_na.lifetime_t1), + be32toh(client->lease->ia.ia_na.lifetime_t2)); return 0; } - timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t1) * USEC_PER_SEC); + timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t1) * USEC_PER_SEC); log_dhcp6_client(client, "T1 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); @@ -1165,7 +1165,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { if (r < 0) goto error; - timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t2) * USEC_PER_SEC); + timeout = client_timeout_compute_random(be32toh(client->lease->ia.ia_na.lifetime_t2) * USEC_PER_SEC); log_dhcp6_client(client, "T2 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 6f604e072f..c0819b7383 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -49,7 +49,7 @@ int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) { valid = t; } - t = be32toh(ia->lifetime_t2); + t = be32toh(ia->ia_na.lifetime_t2); if (t > valid) return -EINVAL; @@ -144,7 +144,7 @@ int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) { assert_return(lease, -EINVAL); assert_return(iaid, -EINVAL); - *iaid = lease->ia.id; + *iaid = lease->ia.ia_na.id; return 0; } -- 2.25.1