From 0e5b94d03845bfb60842014ebb14f153a337954f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 10 Apr 2018 18:45:16 +0200 Subject: [PATCH] dhcp: Increase maximum size of client identification option This increases the chances that subject DNs that might have been cut off with the arbitrary previous limit of 64 bytes might now be sent successfully. The REQUEST message has the most static overhead in terms of other options (17 bytes) as compared to DISCOVER (5) and RELEASE (7). Added to that are 3 bytes for the DHCP message type, which means we have 288 bytes left for the two options based on the client identity (host name and client identification). Since both contain the same value, a FQDN identity, which causes a host name option to get added, may be 142 bytes long, other identities like subject DNs may be 255 bytes long (the maximum for a DHCP option). --- src/libcharon/plugins/dhcp/dhcp_socket.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c index 7b64380b7a..320b17b1ec 100644 --- a/src/libcharon/plugins/dhcp/dhcp_socket.c +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -202,7 +202,7 @@ static int prepare_dhcp(private_dhcp_socket_t *this, chunk_t chunk; identification_t *identity; dhcp_option_t *option; - int optlen = 0; + int optlen = 0, remaining; host_t *src; uint32_t id; @@ -254,21 +254,28 @@ static int prepare_dhcp(private_dhcp_socket_t *this, option->data[0] = type; optlen += sizeof(dhcp_option_t) + option->len; + /* the REQUEST message has the most static overhead in the 'options' field + * with 17 bytes */ + remaining = sizeof(dhcp->options) - optlen - 17; + if (identity->get_type(identity) == ID_FQDN) { option = (dhcp_option_t*)&dhcp->options[optlen]; option->type = DHCP_HOST_NAME; - option->len = min(chunk.len, 64); + option->len = min(min(chunk.len, remaining-sizeof(dhcp_option_t)), 255); memcpy(option->data, chunk.ptr, option->len); optlen += sizeof(dhcp_option_t) + option->len; + remaining -= sizeof(dhcp_option_t) + option->len; } - option = (dhcp_option_t*)&dhcp->options[optlen]; - option->type = DHCP_CLIENT_ID; - option->len = min(chunk.len, 64); - memcpy(option->data, chunk.ptr, option->len); - optlen += sizeof(dhcp_option_t) + option->len; - + if (remaining >= sizeof(dhcp_option_t) + 2) + { + option = (dhcp_option_t*)&dhcp->options[optlen]; + option->type = DHCP_CLIENT_ID; + option->len = min(min(chunk.len, remaining-sizeof(dhcp_option_t)), 255); + memcpy(option->data, chunk.ptr, option->len); + optlen += sizeof(dhcp_option_t) + option->len; + } return optlen; } -- 2.47.2