From aba56902d181f383bfb3d55cb3538e40866f4fdf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 13 Apr 2022 10:57:10 +0200 Subject: [PATCH] Squashed 'src/n-dhcp4/' changes from 281f431756e3..64513e31c01a 64513e31c01a connection: dynamically allocate the receive buffer 2b55ae2f0bda merge branch 'bengal:lease-boot-file' d0f13d174b1a lease: add an accessor for the file name 0c64aedd80bf lease: fix n_dhcp4_client_lease_get_server_identifier() 745ca63afb44 lease: fix typo b9d907d32ec0 Make n_dhcp4_client_lease_get_basetime publicly visible git-subtree-dir: src/n-dhcp4 git-subtree-split: 64513e31c01a88db54c89321f89bcc85da27ffc5 --- src/libndhcp4.sym | 2 ++ src/n-dhcp4-c-connection.c | 17 +++++++++----- src/n-dhcp4-c-lease.c | 46 ++++++++++++++++++++++++++++++++++---- src/n-dhcp4-private.h | 9 -------- src/n-dhcp4.h | 3 ++- src/test-api.c | 1 + 6 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/libndhcp4.sym b/src/libndhcp4.sym index 6c06e2fd28..c6e0dd8672 100644 --- a/src/libndhcp4.sym +++ b/src/libndhcp4.sym @@ -35,8 +35,10 @@ global: n_dhcp4_client_lease_unref; n_dhcp4_client_lease_get_yiaddr; n_dhcp4_client_lease_get_siaddr; + n_dhcp4_client_lease_get_basetime; n_dhcp4_client_lease_get_lifetime; n_dhcp4_client_lease_get_server_identifier; + n_dhcp4_client_lease_get_file; n_dhcp4_client_lease_query; n_dhcp4_client_lease_select; n_dhcp4_client_lease_accept; diff --git a/src/n-dhcp4-c-connection.c b/src/n-dhcp4-c-connection.c index 4aba97393d..45a28de212 100644 --- a/src/n-dhcp4-c-connection.c +++ b/src/n-dhcp4-c-connection.c @@ -1146,16 +1146,21 @@ int n_dhcp4_c_connection_dispatch_timer(NDhcp4CConnection *connection, int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, NDhcp4Incoming **messagep) { _c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *message = NULL; + _c_cleanup_(c_freep) uint8_t *buffer = NULL; char serv_addr[INET_ADDRSTRLEN]; char client_addr[INET_ADDRSTRLEN]; uint8_t type = 0; int r; + buffer = malloc(UINT16_MAX); + if (!buffer) + return -ENOMEM; + switch (connection->state) { case N_DHCP4_C_CONNECTION_STATE_PACKET: r = n_dhcp4_c_socket_packet_recv(connection->fd_packet, - connection->scratch_buffer, - sizeof(connection->scratch_buffer), + buffer, + UINT16_MAX, &message); if (!r) break; @@ -1164,8 +1169,8 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, return N_DHCP4_E_AGAIN; case N_DHCP4_C_CONNECTION_STATE_DRAINING: r = n_dhcp4_c_socket_packet_recv(connection->fd_packet, - connection->scratch_buffer, - sizeof(connection->scratch_buffer), + buffer, + UINT16_MAX, &message); if (!r) break; @@ -1187,8 +1192,8 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection, /* fall-through */ case N_DHCP4_C_CONNECTION_STATE_UDP: r = n_dhcp4_c_socket_udp_recv(connection->fd_udp, - connection->scratch_buffer, - sizeof(connection->scratch_buffer), + buffer, + UINT16_MAX, &message); if (!r) break; diff --git a/src/n-dhcp4-c-lease.c b/src/n-dhcp4-c-lease.c index 515814d4e6..eaa9627652 100644 --- a/src/n-dhcp4-c-lease.c +++ b/src/n-dhcp4-c-lease.c @@ -249,9 +249,11 @@ _c_public_ void n_dhcp4_client_lease_get_lifetime(NDhcp4ClientLease *lease, uint * Gets the address contained in the server-identifier DHCP option, in network * byte order. * - * Return: 0 on success, negative error code on failure. + * Return: 0 on success, + * N_DHCP4_E_UNSET if the lease doesn't contain a server-identifier, or + * N_DHCP4_E_INTERNAL if the server-identifier is not valid. */ -_c_public_ int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *lease, struct in_addr *addr) { +_c_public_ int n_dhcp4_client_lease_get_server_identifier(NDhcp4ClientLease *lease, struct in_addr *addr) { uint8_t *data; size_t n_data; int r; @@ -260,13 +262,49 @@ _c_public_ int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *le if (r) return r; if (n_data < sizeof(struct in_addr)) - return N_DHCP4_E_MALFORMED; + return N_DHCP4_E_INTERNAL; memcpy(addr, data, sizeof(struct in_addr)); return 0; } +/** + * n_dhcp4_client_lease_get_file() - query the lease for the boot file name + * @lease: the lease to operate on + * @file: return argument for the file name + * + * Query the lease for the boot file name from the DHCP header. The file name + * is returned as a NULL-terminated string. + * + * Return: 0 on success, + * N_DHCP4_E_UNSET if the lease does not contain a file name, or + * N_DHCP4_E_INTERNAL if the file name is invalid. + */ +_c_public_ int n_dhcp4_client_lease_get_file(NDhcp4ClientLease *lease, const char **file) { + NDhcp4Message *message; + + if (lease->message->options[N_DHCP4_OPTION_OVERLOAD].size > 0 + && ((*lease->message->options[N_DHCP4_OPTION_OVERLOAD].value) & N_DHCP4_OVERLOAD_FILE)) { + /* The field is overloaded to contain other options */ + return N_DHCP4_E_UNSET; + } + + message = &lease->message->message; + + if (message->file[0] == '\0') + return N_DHCP4_E_UNSET; + + if (!memchr(message->file, '\0', sizeof(message->file))) { + /* The field is NULL-terminated (RFC 2131 section 2) */ + return N_DHCP4_E_INTERNAL; + } + + *file = (const char *) message->file; + + return 0; +} + /** * n_dhcp4_client_lease_query() - query the lease for an option * @lease: the lease to operate on @@ -278,7 +316,7 @@ _c_public_ int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *le * be queried, and only options that were explicitly requested can be queried. * * Return: 0 on success, - * N_DCHP4_E_INTERNAL if an invalid option is queried, + * N_DHCP4_E_INTERNAL if an invalid option is queried, * N_DHCP4_E_UNSET if the lease did not contain the option, or * a negative error code on failure. */ diff --git a/src/n-dhcp4-private.h b/src/n-dhcp4-private.h index db7b24ff7d..8d3f14f5d7 100644 --- a/src/n-dhcp4-private.h +++ b/src/n-dhcp4-private.h @@ -333,15 +333,6 @@ struct NDhcp4CConnection { uint32_t client_ip; /* client IP address, or 0 */ uint32_t server_ip; /* server IP address, or 0 */ uint16_t mtu; /* client mtu, or 0 */ - - /* - * When we get DHCP packets from the kernel, we need a buffer to read - * the data into. Since UDP packets can be up to 2^16 bytes in size, we - * avoid placing it on the stack and instead read into this scratch - * buffer. It is purely meant as stack replacement, no data is returned - * through this buffer. - */ - uint8_t scratch_buffer[UINT16_MAX]; }; #define N_DHCP4_C_CONNECTION_NULL(_x) { \ diff --git a/src/n-dhcp4.h b/src/n-dhcp4.h index 435c5600d8..8493a487dd 100644 --- a/src/n-dhcp4.h +++ b/src/n-dhcp4.h @@ -171,7 +171,8 @@ void n_dhcp4_client_lease_get_siaddr(NDhcp4ClientLease *lease, struct in_addr *s void n_dhcp4_client_lease_get_basetime(NDhcp4ClientLease *lease, uint64_t *ns_basetimep); void n_dhcp4_client_lease_get_lifetime(NDhcp4ClientLease *lease, uint64_t *ns_lifetimep); int n_dhcp4_client_lease_query(NDhcp4ClientLease *lease, uint8_t option, uint8_t **datap, size_t *n_datap); -int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *lease, struct in_addr *addr); +int n_dhcp4_client_lease_get_server_identifier(NDhcp4ClientLease *lease, struct in_addr *addr); +int n_dhcp4_client_lease_get_file(NDhcp4ClientLease *lease, const char **file); int n_dhcp4_client_lease_select(NDhcp4ClientLease *lease); int n_dhcp4_client_lease_accept(NDhcp4ClientLease *lease); diff --git a/src/test-api.c b/src/test-api.c index db3ff935ce..fac3300883 100644 --- a/src/test-api.c +++ b/src/test-api.c @@ -107,6 +107,7 @@ static void test_api_functions(void) { (void *)n_dhcp4_client_lease_get_siaddr, (void *)n_dhcp4_client_lease_get_lifetime, (void *)n_dhcp4_client_lease_get_server_identifier, + (void *)n_dhcp4_client_lease_get_file, (void *)n_dhcp4_client_lease_query, (void *)n_dhcp4_client_lease_select, (void *)n_dhcp4_client_lease_accept,