mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-29 10:17:30 +02:00
Merge pull request #707 from david-cermak/bugfix/sckutls_gethostname
[sock-utils]: Add support for gethostname()
This commit is contained in:
@ -2,5 +2,6 @@ idf_component_register(SRCS "src/getnameinfo.c"
|
||||
"src/ifaddrs.c"
|
||||
"src/gai_strerror.c"
|
||||
"src/socketpair.c"
|
||||
"src/gethostname.c"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES lwip esp_netif)
|
||||
|
@ -13,5 +13,6 @@ This component provides simplified implementations of common socket-related util
|
||||
| `pipe()` | Wraps `socketpair()` to provide unidirectional pipe-like functionality | Uses bidirectional sockets in place of true pipes |
|
||||
| `getnameinfo()` | Converts IP addresses to human-readable form using `lwIP`'s `inet_ntop()` | IPv4 only; supports `NI_NUMERICHOST` and `NI_NUMERICSERV` flags only |
|
||||
| `gai_strerror()` | Returns error code as a string | Simple numeric string representation only |
|
||||
| `gethostname()` | Returns lwip netif hostname | Not a system-wide hostname, but interface specific hostname |
|
||||
|
||||
**Note**: `socketpair()` and `pipe()` are built on top of `lwIP` TCP sockets, inheriting the same characteristics. For instance, the maximum transmit buffer size is based on the `TCP_SND_BUF` setting.
|
||||
|
51
components/sock_utils/include/gethostname.h
Normal file
51
components/sock_utils/include/gethostname.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_LINUX
|
||||
// namespace with esp_ on linux to avoid conflict of symbols
|
||||
#define gethostname esp_gethostname
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Retrieves the hostname of the device.
|
||||
*
|
||||
* This function provides the hostname associated with the network interface.
|
||||
* Unlike the standard behavior where the hostname represents a system-wide name,
|
||||
* this implementation returns lwip netif hostname (used as a hostname in DHCP packets)
|
||||
*
|
||||
* @param[out] name A pointer to a buffer where the hostname will be stored.
|
||||
* The buffer must be allocated by the caller.
|
||||
* @param[in] len The size of the buffer pointed to by @p name. The hostname,
|
||||
* including the null-terminator, must fit within this size.
|
||||
*
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - -1 on error, with `errno` set to indicate the error:
|
||||
* - `EINVAL`: Invalid argument, name is NULL, or hostname is too long
|
||||
*
|
||||
* @note This implementation retrieves the hostname associated with the network
|
||||
* interface using the `esp_netif_get_hostname()` function, which in turn
|
||||
* returns lwip netif hostname used in DHCP packets if LWIP_NETIF_HOSTNAME=1 (hardcoded)
|
||||
* in ESP-IDF lwip port.
|
||||
* As there could be multiple network interfaces in the system, the logic tries
|
||||
* to find the default (active) netif first, then it looks for any (inactive) netif
|
||||
* with highest route priority. If none of the above found or esp_netif_get_hostname() fails
|
||||
* for the selected interface, this API returns the default value of `CONFIG_LWIP_LOCAL_HOSTNAME`,
|
||||
* the local hostname from lwip component configuration menu.
|
||||
*/
|
||||
int gethostname(char *name, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
46
components/sock_utils/src/gethostname.c
Normal file
46
components/sock_utils/src/gethostname.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "gethostname.h"
|
||||
#include "esp_netif.h"
|
||||
#include "errno.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
static bool highest_prio_netif(esp_netif_t *netif, void *ctx)
|
||||
{
|
||||
esp_netif_t **highest_so_far = ctx;
|
||||
if (esp_netif_get_route_prio(netif) > esp_netif_get_route_prio(*highest_so_far)) {
|
||||
*highest_so_far = netif;
|
||||
}
|
||||
return false; // go over the entire list to find the netif with the highest route-prio
|
||||
}
|
||||
|
||||
int gethostname(char *name, size_t len)
|
||||
{
|
||||
if (name == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
const char *netif_hostname = CONFIG_LWIP_LOCAL_HOSTNAME; // default value from Kconfig
|
||||
|
||||
// Find the default netif
|
||||
esp_netif_t *default_netif = esp_netif_get_default_netif();
|
||||
if (default_netif == NULL) { // if no netif is active/up -> find the highest prio netif
|
||||
esp_netif_find_if(highest_prio_netif, &default_netif);
|
||||
}
|
||||
// now the `default_netif` could be NULL and/or the esp_netif_get_hostname() could fail
|
||||
// but we ignore the return code, as if it fails, the `netif_hostname` still holds the default value
|
||||
esp_netif_get_hostname(default_netif, &netif_hostname);
|
||||
|
||||
size_t hostname_len;
|
||||
if (netif_hostname == NULL || len < (hostname_len = strlen(netif_hostname) + 1)) { // including the NULL terminator
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
memcpy(name, netif_hostname, hostname_len);
|
||||
return 0;
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "gethostname.h"
|
||||
#include "ifaddrs.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_event.h"
|
||||
@ -148,6 +149,30 @@ TEST_CASE("gai_strerror()", "[sock_utils]")
|
||||
CHECK(str_error != NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("gethostname()", "[sock_utils]")
|
||||
{
|
||||
const char *test_netif_name = "station";
|
||||
char hostname[32];
|
||||
int ret;
|
||||
|
||||
// expect failure
|
||||
ret = gethostname(hostname, strlen(CONFIG_LWIP_LOCAL_HOSTNAME) - 1);
|
||||
CHECK(ret == -1);
|
||||
|
||||
// happy flow with the default name
|
||||
ret = gethostname(hostname, sizeof(hostname));
|
||||
CHECK(ret == 0);
|
||||
CHECK(strcmp(hostname, CONFIG_LWIP_LOCAL_HOSTNAME) == 0);
|
||||
|
||||
// happy flow with the netif name
|
||||
esp_netif_t *esp_netif = create_test_netif(test_netif_name, 1);
|
||||
REQUIRE(esp_netif != NULL);
|
||||
CHECK(esp_netif_set_hostname(esp_netif, test_netif_name) == ESP_OK);
|
||||
ret = gethostname(hostname, sizeof(hostname));
|
||||
CHECK(ret == 0);
|
||||
CHECK(strcmp(hostname, test_netif_name) == 0);
|
||||
esp_netif_destroy(esp_netif);
|
||||
}
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
|
Reference in New Issue
Block a user