-
Notifications
You must be signed in to change notification settings - Fork 2.1k
sys/net/application_layer: add telnet server module & example #16723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
1b52dee
net/gnrc: restore inclusion of net/gnrc/tcp.h
benpicco 2034fa5
sys/net/application_layer: add telnet server module
benpicco c476abe
examples/telnet_server: add telnet server example
benpicco 2e46e4a
makefiles: warn if telnet is used in auto-init mode
benpicco File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # name of your application | ||
| APPLICATION = telnet_server | ||
|
|
||
| # If no BOARD is found in the environment, use this default: | ||
| BOARD ?= native | ||
|
|
||
| # This has to be the absolute path to the RIOT base directory: | ||
| RIOTBASE ?= $(CURDIR)/../.. | ||
|
|
||
| # Include packages that pull up and auto-init the link layer. | ||
| # NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present | ||
| USEMODULE += netdev_default | ||
| USEMODULE += auto_init_gnrc_netif | ||
| # Activate ICMPv6 error messages | ||
| USEMODULE += gnrc_icmpv6_error | ||
| # Specify the mandatory networking modules for IPv6 | ||
| USEMODULE += gnrc_ipv6_default | ||
| # Additional networking modules that can be dropped if not needed | ||
| USEMODULE += gnrc_icmpv6_echo | ||
| USEMODULE += netutils | ||
| # Add also the shell, some shell commands | ||
| USEMODULE += shell | ||
| USEMODULE += shell_commands | ||
| USEMODULE += ps | ||
| # Include the telnet server | ||
| USEMODULE += stdio_telnet | ||
|
|
||
| # Enable faster re-connects | ||
| CFLAGS += -DCONFIG_GNRC_TCP_EXPERIMENTAL_DYN_MSL_EN=1 | ||
|
|
||
| # Acknowledge that telnet is bad | ||
| I_UNDERSTAND_THAT_TELNET_IS_INSECURE = 1 | ||
|
|
||
| # enable debug output via UART | ||
| FEATURES_OPTIONAL += periph_uart | ||
|
|
||
| # Optionally include DNS support. This includes resolution of names at an | ||
| # upstream DNS server and the handling of RDNSS options in Router Advertisements | ||
| # to auto-configure that upstream DNS server. | ||
| # USEMODULE += sock_dns # include DNS client | ||
| # USEMODULE += gnrc_ipv6_nib_dns # include RDNSS option handling | ||
|
|
||
| # Comment this out to disable code in RIOT that does safety checking | ||
| # which is not needed in a production environment but helps in the | ||
| # development process: | ||
| DEVELHELP ?= 1 | ||
|
|
||
| include $(RIOTBASE)/Makefile.include | ||
|
|
||
| # Set a custom channel if needed | ||
| include $(RIOTMAKE)/default-radio-settings.inc.mk | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| BOARD_INSUFFICIENT_MEMORY := \ | ||
| arduino-duemilanove \ | ||
| arduino-leonardo \ | ||
| arduino-mega2560 \ | ||
| arduino-nano \ | ||
| arduino-uno \ | ||
| atmega1284p \ | ||
| atmega328p \ | ||
| atmega328p-xplained-mini \ | ||
| atxmega-a3bu-xplained \ | ||
| bluepill-stm32f030c8 \ | ||
| derfmega128 \ | ||
| i-nucleo-lrwan1 \ | ||
| mega-xplained \ | ||
| microduino-corerf \ | ||
| msb-430 \ | ||
| msb-430h \ | ||
| nucleo-f030r8 \ | ||
| nucleo-f031k6 \ | ||
| nucleo-f042k6 \ | ||
| nucleo-f303k8 \ | ||
| nucleo-f334r8 \ | ||
| nucleo-l011k4 \ | ||
| nucleo-l031k6 \ | ||
| nucleo-l053r8 \ | ||
| samd10-xmini \ | ||
| stk3200 \ | ||
| slstk3400a \ | ||
| stm32f030f4-demo \ | ||
| stm32f0discovery \ | ||
| stm32g0316-disco \ | ||
| stm32l0538-disco \ | ||
| telosb \ | ||
| waspmote-pro \ | ||
| z1 \ | ||
| zigduino \ | ||
| # |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| /* | ||
| * Copyright (C) 2021 ML!PA Consulting GmbH | ||
| * | ||
| * This file is subject to the terms and conditions of the GNU Lesser | ||
| * General Public License v2.1. See the file LICENSE in the top level | ||
| * directory for more details. | ||
| */ | ||
|
|
||
| /** | ||
| * @ingroup examples | ||
| * @{ | ||
| * | ||
| * @file | ||
| * @brief Example application for demonstrating the RIOT telnet server | ||
| * | ||
| * @author Benjamin Valentin <benjamin.valentin@ml-pa.com> | ||
| * | ||
| * @} | ||
| */ | ||
|
|
||
| #include <stdio.h> | ||
|
|
||
| #include "net/ipv6/addr.h" | ||
| #include "net/gnrc.h" | ||
| #include "net/gnrc/netif.h" | ||
| #include "net/telnet.h" | ||
| #include "shell.h" | ||
| #include "msg.h" | ||
|
|
||
| #define MAIN_QUEUE_SIZE (8) | ||
| static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; | ||
|
|
||
| static void _print_addr(void) | ||
| { | ||
| gnrc_netif_t *netif = NULL; | ||
| while ((netif = gnrc_netif_iter(netif))) { | ||
| ipv6_addr_t ipv6_addrs[CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF]; | ||
| int res = gnrc_netapi_get(netif->pid, NETOPT_IPV6_ADDR, 0, ipv6_addrs, | ||
| sizeof(ipv6_addrs)); | ||
|
|
||
| if (res < 0) { | ||
| continue; | ||
| } | ||
| for (unsigned i = 0; i < (unsigned)(res / sizeof(ipv6_addr_t)); i++) { | ||
| char ipv6_addr[IPV6_ADDR_MAX_STR_LEN]; | ||
|
|
||
| ipv6_addr_to_str(ipv6_addr, &ipv6_addrs[i], IPV6_ADDR_MAX_STR_LEN); | ||
| printf("My address is %s\n", ipv6_addr); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void _print_motd(void) | ||
| { | ||
| puts("RIOT telnet example application"); | ||
|
|
||
| puts("╔═══════════════════════════════════════════════════╗"); | ||
| puts("║telnet is entirely unencrypted and unauthenticated.║"); | ||
| puts("║Do not use this on public networks. ║"); | ||
| puts("╚═══════════════════════════════════════════════════╝"); | ||
| } | ||
|
|
||
| void telnet_cb_pre_connected(sock_tcp_t *sock) | ||
| { | ||
| sock_tcp_ep_t ep; | ||
| char addr_str[IPV6_ADDR_MAX_STR_LEN]; | ||
|
|
||
| sock_tcp_get_local(sock, &ep); | ||
| ipv6_addr_to_str(addr_str, (ipv6_addr_t *)ep.addr.ipv6, sizeof(addr_str)); | ||
|
|
||
| printf("%s connected\n", addr_str); | ||
| } | ||
|
|
||
| void telnet_cb_disconneced(void) | ||
| { | ||
| puts("disconnected"); | ||
| } | ||
|
|
||
| void telnet_cb_connected(sock_tcp_t *sock) | ||
| { | ||
| (void)sock; | ||
| _print_motd(); | ||
| } | ||
|
|
||
| int main(void) | ||
| { | ||
| /* we need a message queue for the thread running the shell in order to | ||
| * receive potentially fast incoming networking packets */ | ||
| msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); | ||
|
|
||
| _print_motd(); | ||
|
|
||
| /* print address so we can connect to it */ | ||
| _print_addr(); | ||
|
|
||
| /* start shell */ | ||
| printf("All up, awaiting connection on port %u\n", CONFIG_TELNET_PORT); | ||
| printf("Local shell disabled"); | ||
| char line_buf[SHELL_DEFAULT_BUFSIZE]; | ||
| shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); | ||
|
|
||
| /* should be never reached */ | ||
| return 0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| /* | ||
| * Copyright (C) 2021 ML!PA Consulting GmbH | ||
| * | ||
| * This file is subject to the terms and conditions of the GNU Lesser | ||
| * General Public License v2.1. See the file LICENSE in the top level | ||
| * directory for more details. | ||
| */ | ||
|
|
||
| /** | ||
| * @defgroup net_telnet basic Telnet server implementation | ||
| * @ingroup net_ipv6 | ||
| * @brief Telnet server functions | ||
| * @{ | ||
| * | ||
| * @file | ||
| * @brief minimal Telnet server ([RFC 854](https://tools.ietf.org/html/rfc854)) implementation | ||
| * @note This implementation only supports a single client and no options. | ||
| * | ||
| * @warning Telnet is entirely unencrypted! Do not use it on public networks. | ||
| * This is intended to aid debugging on networks that are isolated from the Internet. | ||
| * | ||
| * @author Benjamin Valentin <benjamin.valentin@ml-pa.com> | ||
| */ | ||
| #ifndef NET_TELNET_H | ||
| #define NET_TELNET_H | ||
|
|
||
| #include "net/sock/tcp.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| /** | ||
| * @brief The port for the Telnet server to listen on | ||
| */ | ||
| #ifndef CONFIG_TELNET_PORT | ||
| #define CONFIG_TELNET_PORT (23) | ||
| #endif | ||
|
|
||
| /** | ||
| * @brief Start the Telnet server thread | ||
| * | ||
| * @return 0 on success, error otherwise | ||
| */ | ||
| int telnet_server_start(void); | ||
|
|
||
| /** | ||
| * @brief Write data to the telnet client | ||
| * | ||
| * @param[in] buffer The buffer to send to the client | ||
| * @param[in] len The length of the buffer | ||
| * | ||
| * @return 0 on success, error otherwise | ||
| */ | ||
| int telnet_server_write(const void* buffer, size_t len); | ||
|
|
||
| /** | ||
| * @brief Read data from the telnet client, will block until data is available. | ||
| * | ||
| * @param[out] buffer The buffer to write data from the client | ||
| * @param[in] count Number of bytes to read | ||
| * | ||
| * @return number of bytes read, error otherwise | ||
| */ | ||
| int telnet_server_read(void* buffer, size_t count); | ||
|
|
||
| /** | ||
| * @brief Callback function that gets called when a telnet client connects | ||
| * but before stdio is redirected. | ||
| * | ||
| * @param[in] sock Socket of the client that just connected | ||
| * only use with @ref sock_tcp_get_local | ||
| */ | ||
| void telnet_cb_pre_connected(sock_tcp_t *sock); | ||
|
|
||
| /** | ||
| * @brief Callback function that gets called when a telnet client connects | ||
| * after stdio is redirected. | ||
| * | ||
| * @param[in] sock Socket of the client that just connected | ||
| * only use with @ref sock_tcp_get_local | ||
| */ | ||
| void telnet_cb_connected(sock_tcp_t *sock); | ||
|
|
||
| /** | ||
| * @brief Callback function that gets called after a telnet client disconnected. | ||
| */ | ||
| void telnet_cb_disconneced(void); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif /* NET_TELNET_H */ | ||
| /** @} */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.