Skip to content

Commit b80c19d

Browse files
feat(console): Added command getaddrinfo, set/get dnsserver to console_cmd_ping
1 parent 5964ead commit b80c19d

File tree

7 files changed

+589
-10
lines changed

7 files changed

+589
-10
lines changed
+9-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
idf_component_register(SRCS "console_ping.c"
1+
idf_component_register(SRCS "console_ping.c" "console_getaddrinfo.c" "console_getsetdnsserver.c"
22
INCLUDE_DIRS "."
3-
PRIV_REQUIRES esp_netif console
4-
WHOLE_ARCHIVE)
3+
PRIV_REQUIRES esp_netif console)
4+
5+
if(CONFIG_PING_CMD_AUTO_REGISTRATION)
6+
target_link_libraries(${COMPONENT_LIB} "-u console_cmd_ping_register")
7+
target_link_libraries(${COMPONENT_LIB} "-u console_cmd_getaddrinfo_register")
8+
target_link_libraries(${COMPONENT_LIB} "-u console_cmd_setdnsserver_register")
9+
target_link_libraries(${COMPONENT_LIB} "-u console_cmd_getdnsserver_register")
10+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
menu "Ping command Configuration"
2+
3+
config PING_CMD_AUTO_REGISTRATION
4+
bool "Enable Console command ping/dns Auto-registration"
5+
default y
6+
help
7+
Enabling this allows for the autoregistration of the ping and dns commands.
8+
9+
endmenu

components/console_cmd_ping/README.md

+76-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Console command ping
2-
The component provides a console where the 'ping' command can be executed.
1+
# Console command ping and DNS server configuration
2+
The component provides a console where the 'ping' command, 'getaddrinfo', and DNS server configuration commands can be executed.
33

44
## API
55

@@ -27,15 +27,20 @@ The component provides a console where the 'ping' command can be executed.
2727
// Register all plugin command added to your project
2828
ESP_ERROR_CHECK(console_cmd_all_register());
2929

30-
// To register only ifconfig command skip calling console_cmd_all_register()
30+
// To register only ping/dns command skip calling console_cmd_all_register()
3131
ESP_ERROR_CHECK(console_cmd_ping_register());
32+
ESP_ERROR_CHECK(console_cmd_getaddrinfo_register());
33+
ESP_ERROR_CHECK(console_cmd_setdnsserver_register());
34+
ESP_ERROR_CHECK(console_cmd_getdnsserver_register());
3235

3336
ESP_ERROR_CHECK(console_cmd_start()); // Start console
3437
```
3538

3639
### Adding a plugin command or component:
3740
To add a plugin command or any component from IDF component manager into your project, simply include an entry within the `idf_component.yml` file.
3841

42+
Note: **Auto-registration** of a specific plugin command can be disabled from menuconfig.
43+
3944
For more details refer [IDF Component Manager](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html)
4045

4146

@@ -52,4 +57,72 @@ ping [-W <t>] [-i <t>] [-s <n>] [-c <n>] [-Q <n>] [-T <n>] <host>
5257
-Q, --tos=<n> Set Type of Service related bits in IP datagrams
5358
-T, --ttl=<n> Set Time to Live related bits in IP datagrams
5459
<host> Host address
60+
61+
getaddrinfo [-f <AF>] [-F <FLAGS>]... [-p <port>] <hostname>
62+
Usage: getaddrinfo [options] <hostname> [service]
63+
-f, --family=<AF> Address family (AF_INET, AF_INET6, AF_UNSPEC).
64+
-F, --flags=<FLAGS> Special flags (AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, AI_V4MAPPED, AI_ALL).
65+
-p, --port=<port> String containing a numeric port number.
66+
<hostname> Host address
67+
68+
setdnsserver <main> [backup] [fallback]
69+
Usage: setdnsserver <main> [backup] [fallback]
70+
<main> The main DNS server IP address.
71+
backup The secondary DNS server IP address (optional).
72+
fallback The fallback DNS server IP address (optional).
73+
74+
getdnsserver
75+
Usage: getdnsserver
76+
```
77+
These commands allow you to configure and retrieve DNS server settings on your ESP32 device, in addition to the existing ping functionality.
78+
79+
## Usage
80+
### Using the setdnsserver command:
81+
1. To set the main DNS server:
82+
```
83+
setdnsserver 8.8.8.8
84+
```
85+
86+
2. To set the main and backup DNS servers:
87+
88+
```
89+
setdnsserver 8.8.8.8 fe80::b0be:83ff:fe77:dd64
90+
```
91+
92+
3. To set the main, backup, and fallback DNS servers:
93+
94+
```
95+
setdnsserver 8.8.8.8 fe80::b0be:83ff:fe77:dd64 www.xyz.com
96+
```
97+
98+
### Using the getdnsserver command:
99+
To get the current DNS server settings:
100+
```
101+
getdnsserver
102+
```
103+
104+
### Using the getaddrinfo command:
105+
1. To get address information for a hostname:
106+
107+
```
108+
getaddrinfo www.example.com
109+
```
110+
111+
2. To specify additional options:
112+
113+
```
114+
getaddrinfo -f AF_INET -F AI_PASSIVE www.example.com
115+
```
116+
117+
### Using the ping command:
118+
1. To ping a host:
119+
120+
```
121+
ping www.example.com
122+
```
123+
124+
2. To specify additional options, such as timeout, interval, packet size, etc.:
125+
126+
```
127+
ping -W 5 -i 1 -s 64 -c 4 -Q 0x10 -T 64 www.example.com
55128
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <stdio.h>
7+
#include <string.h>
8+
#include "sdkconfig.h"
9+
#include "lwip/inet.h"
10+
#include "lwip/netdb.h"
11+
#include "lwip/sockets.h"
12+
#include "esp_console.h"
13+
#include "esp_log.h"
14+
#include "argtable3/argtable3.h"
15+
#include <netdb.h>
16+
#include "console_ping.h"
17+
18+
19+
static const char *TAG = "console_getaddrinfo";
20+
21+
#if CONFIG_PING_CMD_AUTO_REGISTRATION
22+
/**
23+
* @brief Static registration of the getaddrinfo command plugin.
24+
*
25+
* This section registers the plugin description structure and places it into
26+
* the .console_cmd_desc section, as determined by the linker.lf file in the
27+
* 'plugins' component.
28+
*/
29+
static const console_cmd_plugin_desc_t __attribute__((section(".console_cmd_desc"), used)) PLUGIN = {
30+
.name = "console_cmd_getddrinfo",
31+
.plugin_regd_fn = &console_cmd_getaddrinfo_register
32+
};
33+
#endif
34+
35+
/**
36+
* @brief Structure to hold arguments for the getaddrinfo command.
37+
*/
38+
static struct {
39+
struct arg_str *family;
40+
struct arg_str *flags;
41+
struct arg_str *port_nr;
42+
struct arg_str *hostname;
43+
struct arg_end *end;
44+
} getddrinfo_args;
45+
46+
/**
47+
* @brief Executes the getaddrinfo command.
48+
*
49+
* This function parses arguments, sets hints for address resolution, and calls
50+
* getaddrinfo to resolve the hostname. It then prints the resolved IP addresses
51+
* and associated information.
52+
*
53+
* @param argc Argument count
54+
* @param argv Argument vector
55+
*
56+
* @return int Returns 0 on success, 1 on error.
57+
*/
58+
static int do_getddrinfo_cmd(int argc, char **argv)
59+
{
60+
char ip_str[INET6_ADDRSTRLEN];
61+
struct addrinfo hint = {0};
62+
struct addrinfo *res = NULL, *res_tmp = NULL;
63+
const char *port_nr_str = NULL;
64+
int ret = 0;
65+
66+
int nerrors = arg_parse(argc, argv, (void **)&getddrinfo_args);
67+
if (nerrors != 0) {
68+
arg_print_errors(stderr, getddrinfo_args.end, argv[0]);
69+
return 1;
70+
}
71+
72+
/* Set the address family */
73+
if (getddrinfo_args.family->count > 0) {
74+
if (strcmp(getddrinfo_args.family->sval[0], "AF_INET") == 0) {
75+
hint.ai_family = AF_INET;
76+
} else if (strcmp(getddrinfo_args.family->sval[0], "AF_INET6") == 0) {
77+
hint.ai_family = AF_INET6;
78+
} else if (strcmp(getddrinfo_args.family->sval[0], "AF_UNSPEC") == 0) {
79+
hint.ai_family = AF_UNSPEC;
80+
} else {
81+
ESP_LOGE(TAG, "Unknown family");
82+
return 1;
83+
}
84+
}
85+
86+
/* Set the flags */
87+
if (getddrinfo_args.flags->count > 0) {
88+
for (int i = 0; i < getddrinfo_args.flags->count; i++) {
89+
if (strcmp(getddrinfo_args.flags->sval[i], "AI_PASSIVE") == 0) {
90+
hint.ai_flags |= AI_PASSIVE;
91+
} else if (strcmp(getddrinfo_args.flags->sval[i], "AI_CANONNAME") == 0) {
92+
hint.ai_flags |= AI_CANONNAME;
93+
} else if (strcmp(getddrinfo_args.flags->sval[i], "AI_NUMERICHOST") == 0) {
94+
hint.ai_flags |= AI_NUMERICHOST;
95+
} else if (strcmp(getddrinfo_args.flags->sval[i], "AI_V4MAPPED") == 0) {
96+
hint.ai_flags |= AI_V4MAPPED;
97+
} else if (strcmp(getddrinfo_args.flags->sval[i], "AI_ALL") == 0) {
98+
hint.ai_flags |= AI_ALL;
99+
} else {
100+
ESP_LOGE(TAG, "Unknown flag: %s", getddrinfo_args.flags->sval[i]);
101+
return 1;
102+
}
103+
}
104+
}
105+
106+
if (getddrinfo_args.port_nr->count > 0) {
107+
port_nr_str = getddrinfo_args.port_nr->sval[0];
108+
}
109+
110+
/* Convert hostname to IP address */
111+
if (!strcmp(getddrinfo_args.hostname->sval[0], "NULL")) {
112+
ret = getaddrinfo(NULL, port_nr_str, &hint, &res);
113+
} else {
114+
ret = getaddrinfo(getddrinfo_args.hostname->sval[0], port_nr_str, &hint, &res);
115+
}
116+
117+
if (ret != 0) {
118+
printf("getddrinfo: Failure host:%s(ERROR: %d)\n", getddrinfo_args.hostname->sval[0], ret);
119+
ESP_LOGE(TAG, "Failure host");
120+
return 1;
121+
}
122+
123+
/* Iterate through the results from getaddrinfo */
124+
for (res_tmp = res; res_tmp != NULL; res_tmp = res_tmp->ai_next) {
125+
126+
if (res_tmp->ai_family == AF_INET) {
127+
inet_ntop(AF_INET, &((struct sockaddr_in *)res_tmp->ai_addr)->sin_addr, ip_str, INET_ADDRSTRLEN);
128+
printf("\tIP Address: %s\n", ip_str);
129+
printf("\tAddress Family: AF_INET\n");
130+
} else if (res_tmp->ai_family == AF_INET6) {
131+
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res_tmp->ai_addr)->sin6_addr, ip_str, INET6_ADDRSTRLEN);
132+
printf("\tIP Address: %s\n", ip_str);
133+
printf("\tAddress Family: AF_INET6\n");
134+
} else {
135+
ESP_LOGE(TAG, "ai_family Unknown: %d\n", res_tmp->ai_family);
136+
}
137+
138+
/* Print the protocol used */
139+
printf("\tProtocol: %d\n", res_tmp->ai_protocol);
140+
141+
/* Print the canonical name if available */
142+
if (res_tmp->ai_canonname) {
143+
printf("\tCanonical Name: %s\n", res_tmp->ai_canonname);
144+
}
145+
}
146+
147+
freeaddrinfo(res);
148+
149+
return 0;
150+
}
151+
152+
/**
153+
* @brief Registers the getaddrinfo command.
154+
*
155+
* @return esp_err_t Returns ESP_OK on success, or an error code on failure.
156+
*/
157+
esp_err_t console_cmd_getaddrinfo_register(void)
158+
{
159+
esp_err_t ret;
160+
161+
getddrinfo_args.family = arg_str0("f", "family", "<AF>", "Address family (AF_INET, AF_INET6, AF_UNSPEC).");
162+
getddrinfo_args.flags = arg_strn("F", "flags", "<FLAGS>", 0, 5, "Special flags (AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST, AI_V4MAPPED, AI_ALL).");
163+
getddrinfo_args.port_nr = arg_str0("p", "port", "<port>", "String containing a numeric port number.");
164+
getddrinfo_args.hostname = arg_str1(NULL, NULL, "<hostname>", "Host address");
165+
getddrinfo_args.end = arg_end(1);
166+
const esp_console_cmd_t getddrinfo_cmd = {
167+
.command = "getaddrinfo",
168+
.help = "Usage: getaddrinfo [options] <hostname> [service]",
169+
.hint = NULL,
170+
.func = &do_getddrinfo_cmd,
171+
.argtable = &getddrinfo_args
172+
};
173+
174+
ret = esp_console_cmd_register(&getddrinfo_cmd);
175+
if (ret) {
176+
ESP_LOGE(TAG, "Unable to register getddrinfo");
177+
}
178+
179+
return ret;
180+
}

0 commit comments

Comments
 (0)