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/ifaddrs.c"
|
||||||
"src/gai_strerror.c"
|
"src/gai_strerror.c"
|
||||||
"src/socketpair.c"
|
"src/socketpair.c"
|
||||||
|
"src/gethostname.c"
|
||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include"
|
||||||
PRIV_REQUIRES lwip esp_netif)
|
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 |
|
| `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 |
|
| `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 |
|
| `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.
|
**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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
#include "gethostname.h"
|
||||||
#include "ifaddrs.h"
|
#include "ifaddrs.h"
|
||||||
#include "esp_netif.h"
|
#include "esp_netif.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
@ -148,6 +149,30 @@ TEST_CASE("gai_strerror()", "[sock_utils]")
|
|||||||
CHECK(str_error != NULL);
|
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)
|
extern "C" void app_main(void)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user