netutils: Support telnetd in the kernel mode
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
parent
12863fbd52
commit
36a0c924f7
@ -27,8 +27,8 @@ MAINSRC = telnetd.c
|
||||
# Buttons built-in application info
|
||||
|
||||
PROGNAME = telnetd
|
||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
|
||||
PRIORITY = $(CONFIG_EXAMPLES_TELNETD_DAEMONPRIO)
|
||||
STACKSIZE = $(CONFIG_EXAMPLES_TELNETD_DAEMONSTACKSIZE)
|
||||
MODULE = $(CONFIG_EXAMPLES_TELNETD)
|
||||
|
||||
include $(APPDIR)/Application.mk
|
||||
|
@ -239,10 +239,9 @@ int main(int argc, FAR char *argv[])
|
||||
|
||||
/* Configure the telnet daemon */
|
||||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.d_port = HTONS(23);
|
||||
config.d_family = AF_INET;
|
||||
config.d_priority = CONFIG_EXAMPLES_TELNETD_DAEMONPRIO;
|
||||
config.d_stacksize = CONFIG_EXAMPLES_TELNETD_DAEMONSTACKSIZE;
|
||||
config.t_priority = CONFIG_EXAMPLES_TELNETD_CLIENTPRIO;
|
||||
config.t_stacksize = CONFIG_EXAMPLES_TELNETD_CLIENTSTACKSIZE;
|
||||
config.t_entry = telnetd_session;
|
||||
@ -250,7 +249,7 @@ int main(int argc, FAR char *argv[])
|
||||
/* Start the telnet daemon */
|
||||
|
||||
printf("telnetd_main: Starting the Telnet daemon\n");
|
||||
ret = telnetd_start(&config);
|
||||
ret = telnetd_daemon(&config);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Failed to start the Telnet daemon\n");
|
||||
|
@ -25,44 +25,38 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* CONFIG_TELNETD_CONSOLE - Use the first Telnet session as the default
|
||||
* console.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* An instance of the struct telnetd_config_s structure must be passed to
|
||||
* telnetd_start in order to configure the new Telnet daemon.
|
||||
* telnetd_daemon in order to configure the new Telnet daemon.
|
||||
*/
|
||||
|
||||
struct telnetd_config_s
|
||||
{
|
||||
/* These fields describe the telnet daemon */
|
||||
|
||||
uint8_t d_priority; /* The execution priority of the Telnet daemon task */
|
||||
size_t d_stacksize; /* The stack size needed by the Telnet daemon task */
|
||||
|
||||
/* These fields describe the network connection */
|
||||
|
||||
uint16_t d_port; /* The port to listen on (in network byte order) */
|
||||
sa_family_t d_family; /* Address family */
|
||||
uint16_t d_port; /* The port to listen on (in network byte order) */
|
||||
sa_family_t d_family; /* Address family */
|
||||
|
||||
/* These fields describe the priority of each thread created by the Telnet
|
||||
/* These fields describe the priority of each task created by the Telnet
|
||||
* daemon.
|
||||
*/
|
||||
|
||||
uint8_t t_priority; /* The execution priority of the spawned task, */
|
||||
size_t t_stacksize; /* The stack size needed by the spawned task */
|
||||
main_t t_entry; /* The entrypoint of the task to spawn when a new
|
||||
* connection is accepted. */
|
||||
uint8_t t_priority; /* The execution priority of the spawned task, */
|
||||
size_t t_stacksize; /* The stack size needed by the spawned task */
|
||||
#ifndef CONFIG_BUILD_KERNEL
|
||||
main_t t_entry; /* The entrypoint of the task to spawn when a new
|
||||
* connection is accepted. */
|
||||
#endif
|
||||
#ifdef CONFIG_LIBC_EXECFUNCS
|
||||
FAR const char *t_path; /* The binary path of the task to spawn when a new
|
||||
* connection is accepted. */
|
||||
#endif
|
||||
FAR char * const *t_argv; /* The argument pass to the spawned task */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -78,10 +72,10 @@ extern "C"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: telnetd_start
|
||||
* Name: telnetd_daemon
|
||||
*
|
||||
* Description:
|
||||
* Start the Telnet daemon.
|
||||
* Run the Telnet daemon loop.
|
||||
*
|
||||
* Parameters:
|
||||
* config A pointer to a configuration structure that characterizes the
|
||||
@ -90,13 +84,11 @@ extern "C"
|
||||
* daemon.
|
||||
*
|
||||
* Return:
|
||||
* The process ID (pid) of the new Telnet daemon is returned on
|
||||
* success; A negated errno is returned if the daemon was not successfully
|
||||
* started.
|
||||
* A negated errno is returned if the daemon was not successfully started.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int telnetd_start(FAR struct telnetd_config_s *config);
|
||||
int telnetd_daemon(FAR const struct telnetd_config_s *config);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -10,6 +10,3 @@ config NETUTILS_TELNETD
|
||||
select NETDEV_TELNET
|
||||
---help---
|
||||
Enable support for the Telnet daemon.
|
||||
|
||||
if NETUTILS_TELNETD
|
||||
endif
|
||||
|
@ -22,8 +22,6 @@ include $(APPDIR)/Make.defs
|
||||
|
||||
# Telnet daemon
|
||||
|
||||
ifeq ($(CONFIG_NET_TCP),y)
|
||||
CSRCS = telnetd_daemon.c
|
||||
endif
|
||||
|
||||
include $(APPDIR)/Application.mk
|
||||
|
@ -24,52 +24,24 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <spawn.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <nuttx/net/telnet.h>
|
||||
|
||||
#include "netutils/telnetd.h"
|
||||
#include "netutils/netlib.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure represents the overall state of one telnet daemon instance
|
||||
* (Yes, multiple telnet daemons are supported).
|
||||
*/
|
||||
|
||||
struct telnetd_s
|
||||
{
|
||||
uint16_t port; /* The port to listen on (in network byte order) */
|
||||
sa_family_t family; /* Address family */
|
||||
uint8_t priority; /* The execution priority of the spawned task, */
|
||||
size_t stacksize; /* The stack size needed by the spawned task */
|
||||
main_t entry; /* The entrypoint of the task to spawn when a new
|
||||
* connection is accepted. */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@ -87,11 +59,8 @@ struct telnetd_s
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
int telnetd_daemon(FAR const struct telnetd_config_s *config)
|
||||
{
|
||||
UNUSED(argc);
|
||||
|
||||
FAR struct telnetd_s *daemon;
|
||||
union
|
||||
{
|
||||
struct sockaddr generic;
|
||||
@ -103,29 +72,16 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
#endif
|
||||
} addr;
|
||||
|
||||
struct telnet_session_s session;
|
||||
#ifdef CONFIG_NET_SOLINGER
|
||||
struct linger ling;
|
||||
#endif
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
struct sigaction sa;
|
||||
sigset_t blockset;
|
||||
#endif
|
||||
socklen_t addrlen;
|
||||
pid_t pid;
|
||||
int listensd;
|
||||
int acceptsd;
|
||||
int drvrfd;
|
||||
#ifdef CONFIG_NET_SOCKOPTS
|
||||
int optval;
|
||||
#endif
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
/* Get daemon startup info */
|
||||
|
||||
daemon = (FAR struct telnetd_s *)((uintptr_t)strtoul(argv[1], NULL, 0));
|
||||
DEBUGASSERT(daemon != NULL);
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
/* Call sigaction with the SA_NOCLDWAIT flag so that we do not transform
|
||||
@ -143,7 +99,7 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
if (sigaction(SIGCHLD, &sa, NULL) < 0)
|
||||
{
|
||||
nerr("ERROR: sigaction failed: %d\n", errno);
|
||||
goto errout_with_daemon;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Block receipt of the SIGCHLD signal */
|
||||
@ -153,18 +109,18 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
if (sigprocmask(SIG_BLOCK, &blockset, NULL) < 0)
|
||||
{
|
||||
nerr("ERROR: sigprocmask failed: %d\n", errno);
|
||||
goto errout_with_daemon;
|
||||
goto errout;
|
||||
}
|
||||
#endif /* CONFIG_SCHED_HAVE_PARENT */
|
||||
|
||||
/* Create a new TCP socket to use to listen for connections */
|
||||
|
||||
listensd = socket(daemon->family, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
listensd = socket(config->d_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (listensd < 0)
|
||||
{
|
||||
nerr("ERROR: socket() failed for family %u: %d\n",
|
||||
daemon->family, errno);
|
||||
goto errout_with_daemon;
|
||||
config->d_family, errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_SOCKOPTS
|
||||
@ -172,7 +128,7 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(FAR void *)&optval, sizeof(int)) < 0)
|
||||
&optval, sizeof(int)) < 0)
|
||||
{
|
||||
nerr("ERROR: setsockopt SO_REUSEADDR failure: %d\n", errno);
|
||||
goto errout_with_socket;
|
||||
@ -182,20 +138,20 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
/* Bind the socket to a local address */
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if (daemon->family == AF_INET)
|
||||
if (config->d_family == AF_INET)
|
||||
{
|
||||
addr.ipv4.sin_family = AF_INET;
|
||||
addr.ipv4.sin_port = daemon->port;
|
||||
addr.ipv4.sin_port = config->d_port;
|
||||
addr.ipv4.sin_addr.s_addr = INADDR_ANY;
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (daemon->family == AF_INET6)
|
||||
if (config->d_family == AF_INET6)
|
||||
{
|
||||
addr.ipv6.sin6_family = AF_INET6;
|
||||
addr.ipv6.sin6_port = daemon->port;
|
||||
addr.ipv6.sin6_port = config->d_port;
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
|
||||
memset(addr.ipv6.sin6_addr.s6_addr, 0,
|
||||
@ -204,7 +160,7 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nerr("ERROR: Unsupported address family: %u", daemon->family);
|
||||
nerr("ERROR: Unsupported address family: %u", config->d_family);
|
||||
goto errout_with_socket;
|
||||
}
|
||||
|
||||
@ -222,24 +178,26 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
goto errout_with_socket;
|
||||
}
|
||||
|
||||
/* Now go silent. */
|
||||
|
||||
#ifndef CONFIG_DEBUG_FEATURES
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
#endif
|
||||
|
||||
/* Begin accepting connections */
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
socklen_t accptlen;
|
||||
struct telnet_session_s session;
|
||||
#ifdef CONFIG_NET_SOLINGER
|
||||
struct linger ling;
|
||||
#endif
|
||||
int drvrfd;
|
||||
|
||||
ninfo("Accepting connections on port %d\n", ntohs(daemon->port));
|
||||
/* Now go silent. */
|
||||
|
||||
accptlen = sizeof(addr);
|
||||
acceptsd = accept(listensd, &addr.generic, &accptlen);
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
ninfo("Accepting connections on port %d\n", ntohs(config->d_port));
|
||||
|
||||
addrlen = sizeof(addr);
|
||||
acceptsd = accept(listensd, &addr.generic, &addrlen);
|
||||
if (acceptsd < 0)
|
||||
{
|
||||
/* Just continue if a signal was received */
|
||||
@ -272,8 +230,8 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
|
||||
/* Open the Telnet factory */
|
||||
|
||||
fd = open("/dev/telnet", O_RDONLY);
|
||||
if (fd < 0)
|
||||
drvrfd = open("/dev/telnet", O_RDONLY);
|
||||
if (drvrfd < 0)
|
||||
{
|
||||
nerr("ERROR: open(/dev/telnet) failed: %d\n", errno);
|
||||
goto errout_with_acceptsd;
|
||||
@ -286,15 +244,16 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
session.ts_sd = acceptsd;
|
||||
session.ts_devpath[0] = '\0';
|
||||
|
||||
ret = ioctl(fd, SIOCTELNET, (unsigned long)((uintptr_t)&session));
|
||||
close(fd);
|
||||
|
||||
if (ret < 0)
|
||||
if (ioctl(drvrfd, SIOCTELNET,
|
||||
(unsigned long)((uintptr_t)&session)) < 0)
|
||||
{
|
||||
nerr("ERROR: open(/dev/telnet) failed: %d\n", errno);
|
||||
close(drvrfd);
|
||||
goto errout_with_acceptsd;
|
||||
}
|
||||
|
||||
close(drvrfd);
|
||||
|
||||
/* Open the driver */
|
||||
|
||||
ninfo("Opening the telnet driver at %s\n", session.ts_devpath);
|
||||
@ -323,19 +282,46 @@ static int telnetd_daemon(int argc, FAR char *argv[])
|
||||
*/
|
||||
|
||||
ninfo("Starting the telnet session\n");
|
||||
pid = task_create("Telnet session", daemon->priority,
|
||||
daemon->stacksize, daemon->entry, NULL);
|
||||
if (pid < 0)
|
||||
|
||||
#ifndef CONFIG_BUILD_KERNEL
|
||||
if (config->t_entry)
|
||||
{
|
||||
nerr("ERROR: Failed start the telnet session: %d\n", errno);
|
||||
goto errout_with_socket;
|
||||
pid_t pid = task_create("Telnet session",
|
||||
config->t_priority, config->t_stacksize,
|
||||
config->t_entry, NULL);
|
||||
if (pid >= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Forget about the connection. */
|
||||
#ifdef CONFIG_LIBC_EXECFUNCS
|
||||
if (config->t_path)
|
||||
{
|
||||
struct sched_param param;
|
||||
posix_spawnattr_t attr;
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
sched_getparam(0, ¶m);
|
||||
param.sched_priority = config->t_priority;
|
||||
|
||||
posix_spawnattr_init(&attr);
|
||||
posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM);
|
||||
posix_spawnattr_setschedparam(&attr, ¶m);
|
||||
posix_spawnattr_setstacksize(&attr, config->t_stacksize);
|
||||
|
||||
ret = posix_spawnp(&pid, config->t_path, NULL,
|
||||
&attr, config->t_argv, NULL);
|
||||
if (ret > 0)
|
||||
{
|
||||
nerr("ERROR: Failed start the telnet session: %d\n", ret);
|
||||
errno = ret;
|
||||
goto errout_with_socket;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
errout_with_acceptsd:
|
||||
@ -343,74 +329,6 @@ errout_with_acceptsd:
|
||||
|
||||
errout_with_socket:
|
||||
close(listensd);
|
||||
errout_with_daemon:
|
||||
free(daemon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: telnetd_start
|
||||
*
|
||||
* Description:
|
||||
* Start the telnet daemon.
|
||||
*
|
||||
* Parameters:
|
||||
* config A pointer to a configuration structure that characterizes the
|
||||
* telnet daemon. This configuration structure may be defined
|
||||
* on the caller's stack because it is not retained by the
|
||||
* daemon.
|
||||
*
|
||||
* Return:
|
||||
* The process ID (pid) of the new telnet daemon is returned on
|
||||
* success; A negated errno is returned if the daemon was not successfully
|
||||
* started.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int telnetd_start(FAR struct telnetd_config_s *config)
|
||||
{
|
||||
FAR struct telnetd_s *daemon;
|
||||
FAR char *argv[2];
|
||||
char arg0[sizeof("0x1234567812345678")];
|
||||
pid_t pid;
|
||||
|
||||
/* Allocate a state structure for the new daemon */
|
||||
|
||||
daemon = (FAR struct telnetd_s *)malloc(sizeof(struct telnetd_s));
|
||||
if (!daemon)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Initialize the daemon structure */
|
||||
|
||||
daemon->port = config->d_port;
|
||||
daemon->family = config->d_family;
|
||||
daemon->priority = config->t_priority;
|
||||
daemon->stacksize = config->t_stacksize;
|
||||
daemon->entry = config->t_entry;
|
||||
|
||||
/* Then start the new daemon */
|
||||
|
||||
snprintf(arg0, sizeof(arg0), "0x%" PRIxPTR, (uintptr_t)daemon);
|
||||
argv[0] = arg0;
|
||||
argv[1] = NULL;
|
||||
|
||||
pid = task_create("Telnet daemon", config->d_priority, config->d_stacksize,
|
||||
telnetd_daemon, argv);
|
||||
if (pid < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
free(daemon);
|
||||
nerr("ERROR: Failed to start the telnet daemon: %d\n", errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
|
||||
return pid;
|
||||
errout:
|
||||
return errno;
|
||||
}
|
||||
|
@ -546,10 +546,6 @@ config NSH_DISABLE_TEST
|
||||
bool "Disable test"
|
||||
default DEFAULT_SMALL
|
||||
|
||||
config NSH_DISABLE_TELNETD
|
||||
bool "Disable telnetd"
|
||||
default DEFAULT_SMALL || NSH_NETLOCAL
|
||||
|
||||
config NSH_DISABLE_TRUNCATE
|
||||
bool "Disable truncate"
|
||||
default DEFAULT_SMALL
|
||||
@ -1156,65 +1152,24 @@ endif # NSH_DISABLE_WGET
|
||||
endmenu # Networking Configuration"
|
||||
|
||||
menu "Telnet Configuration"
|
||||
depends on NETUTILS_TELNETD
|
||||
|
||||
config NSH_TELNET
|
||||
bool "Use Telnet console"
|
||||
default !DEFAULT_SMALL
|
||||
depends on NETUTILS_TELNETD
|
||||
depends on SYSTEM_TELNETD
|
||||
---help---
|
||||
If NSH_TELNET is set to 'y', then a TELENET
|
||||
server front-end is selected. When this option is provided,
|
||||
you may log into NuttX remotely using telnet in order to
|
||||
access NSH.
|
||||
|
||||
if NSH_TELNET
|
||||
|
||||
config NSH_TELNETD_PORT
|
||||
int "Telnet port number"
|
||||
default 23
|
||||
---help---
|
||||
The telnet daemon will listen on this TCP port number for connections.
|
||||
Default: 23
|
||||
|
||||
config NSH_TELNETD_DAEMONPRIO
|
||||
int "Telnet daemon priority"
|
||||
default 100
|
||||
---help---
|
||||
Priority of the Telnet daemon. Default: 100
|
||||
|
||||
config NSH_TELNETD_DAEMONSTACKSIZE
|
||||
int "Telnet daemon stack size"
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
---help---
|
||||
Stack size allocated for the Telnet daemon. Default: 2048
|
||||
|
||||
config NSH_TELNETD_CLIENTPRIO
|
||||
int "Telnet client priority"
|
||||
default 100
|
||||
---help---
|
||||
Priority of the Telnet client. Default: 100
|
||||
|
||||
config NSH_TELNETD_CLIENTSTACKSIZE
|
||||
int "Telnet client stack size"
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
---help---
|
||||
Stack size allocated for the Telnet client. Default: 2048
|
||||
|
||||
config NSH_IOBUFFER_SIZE
|
||||
int "Telnet I/O buffer size"
|
||||
default 512
|
||||
---help---
|
||||
Determines the size of the I/O buffer to use for sending/
|
||||
receiving TELNET commands/responses. Default: 512
|
||||
|
||||
config NSH_DISABLE_TELNETSTART
|
||||
bool "Disable to start telnetd"
|
||||
default false
|
||||
default DEFAULT_SMALL
|
||||
depends on NSH_TELNET
|
||||
---help---
|
||||
Determines if the nsh starts telnetd automatically
|
||||
|
||||
endif # NSH_TELNET
|
||||
endmenu # Telnet Configuration
|
||||
|
||||
config NSH_LOGIN
|
||||
|
@ -1343,7 +1343,7 @@ system image.
|
||||
`nsh_telnetstart()` or it may be started from the NSH command line using this
|
||||
`telnetd` command.
|
||||
|
||||
Normally this command would be suppressed with `CONFIG_NSH_DISABLE_TELNETD`
|
||||
Normally this command would be suppressed without `CONFIG_SYSTEM_TELNETD`
|
||||
because the Telnet daemon is automatically started in `nsh_main.c`. The
|
||||
exception is when `CONFIG_NETINIT_NETLOCAL` is selected. IN that case, the
|
||||
network is not enabled at initialization but rather must be enabled from the
|
||||
@ -1618,7 +1618,7 @@ shutdown | `CONFIG_BOARDCTL_POWEROFF` || `CONFIG_BOARDCTL_RESET`
|
||||
sleep | -
|
||||
source | `CONFIG_FILE_STREAM` && !`CONFIG_NSH_DISABLESCRIPT`
|
||||
test | !`CONFIG_NSH_DISABLESCRIPT`
|
||||
telnetd | `CONFIG_NSH_TELNET` && !`CONFIG_NSH_DISABLE_TELNETD`
|
||||
telnetd | `CONFIG_NSH_TELNET` && `CONFIG_SYSTEM_TELNETD`
|
||||
time | -
|
||||
truncate | !`CONFIG_DISABLE_MOUNTPOINT`
|
||||
umount | !`CONFIG_DISABLE_MOUNTPOINT`
|
||||
@ -1915,16 +1915,16 @@ The behavior of NSH can be modified with the following settings in the
|
||||
If Telnet is selected for the NSH console, then we must configure the resources
|
||||
used by the Telnet daemon and by the Telnet clients.
|
||||
|
||||
- `CONFIG_NSH_TELNETD_PORT` – The telnet daemon will listen on this TCP port
|
||||
- `CONFIG_SYSTEM_TELNETD_PORT` – The telnet daemon will listen on this TCP port
|
||||
number for connections. Default: `23`
|
||||
- `CONFIG_NSH_TELNETD_DAEMONPRIO` – Priority of the Telnet daemon. Default:
|
||||
- `CONFIG_SYSTEM_TELNETD_PRIORITY` – Priority of the Telnet daemon. Default:
|
||||
`SCHED_PRIORITY_DEFAULT`
|
||||
- `CONFIG_NSH_TELNETD_DAEMONSTACKSIZE` – Stack size allocated for the Telnet
|
||||
- `CONFIG_SYSTEM_TELNETD_STACKSIZE` – Stack size allocated for the Telnet
|
||||
daemon. Default: `2048`
|
||||
- `CONFIG_NSH_TELNETD_CLIENTPRIO` – Priority of the Telnet client. Default:
|
||||
- `CONFIG_SYSTEM_TELNETD_SESSION_PRIORITY` – Priority of the Telnet client. Default:
|
||||
`SCHED_PRIORITY_DEFAULT`
|
||||
- `CONFIG_NSH_TELNETD_CLIENTSTACKSIZE` – Stack size allocated for the Telnet
|
||||
client. Default: `2048`
|
||||
- `CONFIG_SYSTEM_TELNETD_SESSION_STACKSIZE` – Stack size allocated for the Telnet
|
||||
client. Default: `3072`
|
||||
|
||||
One or both of CONFIG_NSH_CONSOLE and `CONFIG_NSH_TELNET` must be defined. If
|
||||
`CONFIG_NSH_TELNET` is selected, then there some other configuration settings
|
||||
@ -1933,8 +1933,6 @@ that apply:
|
||||
- `CONFIG_NET=y` – Of course, networking must be enabled
|
||||
- `CONFIG_NET_TCP=y` – TCP/IP support is required for telnet (as well as various
|
||||
other TCP-related configuration settings).
|
||||
- `CONFIG_NSH_IOBUFFER_SIZE` – Determines the size of the I/O buffer to use for
|
||||
sending/ receiving TELNET commands/responses.
|
||||
- `CONFIG_NETINIT_DHCPC` – Obtain the IP address via DHCP.
|
||||
- `CONFIG_NETINIT_IPADDR` – If `CONFIG_NETINIT_DHCPC` is NOT set, then the
|
||||
static IP address must be provided.
|
||||
|
41
nshlib/nsh.h
41
nshlib/nsh.h
@ -264,16 +264,6 @@
|
||||
/* If Telnet is selected for the NSH console, then we must configure
|
||||
* the resources used by the Telnet daemon and by the Telnet clients.
|
||||
*
|
||||
* CONFIG_NSH_TELNETD_PORT - The telnet daemon will listen on this.
|
||||
* port. Default: 23
|
||||
* CONFIG_NSH_TELNETD_DAEMONPRIO - Priority of the Telnet daemon.
|
||||
* Default: SCHED_PRIORITY_DEFAULT
|
||||
* CONFIG_NSH_TELNETD_DAEMONSTACKSIZE - Stack size allocated for the
|
||||
* Telnet daemon. Default: 2048
|
||||
* CONFIG_NSH_TELNETD_CLIENTPRIO - Priority of the Telnet client.
|
||||
* Default: SCHED_PRIORITY_DEFAULT
|
||||
* CONFIG_NSH_TELNETD_CLIENTSTACKSIZE - Stack size allocated for the
|
||||
* Telnet client. Default: 2048
|
||||
* CONFIG_NSH_TELNET_LOGIN - Support a simple Telnet login.
|
||||
*
|
||||
* If CONFIG_NSH_TELNET_LOGIN is defined, then these additional
|
||||
@ -285,26 +275,6 @@
|
||||
* Default 3.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_NSH_TELNETD_PORT
|
||||
# define CONFIG_NSH_TELNETD_PORT 23
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_TELNETD_DAEMONPRIO
|
||||
# define CONFIG_NSH_TELNETD_DAEMONPRIO SCHED_PRIORITY_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_TELNETD_DAEMONSTACKSIZE
|
||||
# define CONFIG_NSH_TELNETD_DAEMONSTACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_TELNETD_CLIENTPRIO
|
||||
# define CONFIG_NSH_TELNETD_CLIENTPRIO SCHED_PRIORITY_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_TELNETD_CLIENTSTACKSIZE
|
||||
# define CONFIG_NSH_TELNETD_CLIENTSTACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NSH_TELNET_LOGIN
|
||||
|
||||
# ifndef CONFIG_NSH_LOGIN_USERNAME
|
||||
@ -447,12 +417,6 @@
|
||||
# define CONFIG_NSH_LINELEN 80
|
||||
#endif
|
||||
|
||||
/* The following two settings are used only in the telnetd interface */
|
||||
|
||||
#ifndef CONFIG_NSH_IOBUFFER_SIZE
|
||||
# define CONFIG_NSH_IOBUFFER_SIZE 512
|
||||
#endif
|
||||
|
||||
/* The maximum number of nested if-then[-else]-fi sequences that
|
||||
* are permissible.
|
||||
*/
|
||||
@ -1152,11 +1116,6 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
|
||||
# ifndef CONFIG_NSH_DISABLE_ROUTE
|
||||
int cmd_route(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
|
||||
# endif
|
||||
# if defined(CONFIG_NSH_TELNET)
|
||||
# ifndef CONFIG_NSH_DISABLE_TELNETD
|
||||
int cmd_telnetd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
|
||||
# endif
|
||||
# endif
|
||||
#endif /* CONFIG_NET */
|
||||
|
||||
#if defined(CONFIG_LIBC_NETDB) && !defined(CONFIG_NSH_DISABLE_NSLOOKUP)
|
||||
|
@ -521,14 +521,6 @@ static const struct cmdmap_s g_cmdmap[] =
|
||||
{ "test", cmd_test, 3, CONFIG_NSH_MAXARGUMENTS, "<expression>" },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NSH_TELNET) && !defined(CONFIG_NSH_DISABLE_TELNETD)
|
||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||
{"telnetd", cmd_telnetd, 2, 2, "[ipv4|ipv6]" },
|
||||
#else
|
||||
{"telnetd", cmd_telnetd, 1, 1, NULL },
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLE_TIME
|
||||
{ "time", cmd_time, 2, 2, "\"<command>\"" },
|
||||
#endif
|
||||
|
@ -24,39 +24,16 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "netutils/telnetd.h"
|
||||
|
||||
#ifdef CONFIG_TELNET_CHARACTER_MODE
|
||||
#ifdef CONFIG_NSH_CLE
|
||||
# include "system/cle.h"
|
||||
#else
|
||||
# include "system/readline.h"
|
||||
#endif
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "nsh.h"
|
||||
#include "nsh_console.h"
|
||||
|
||||
#ifdef CONFIG_NSH_TELNET
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
enum telnetd_state_e
|
||||
{
|
||||
TELNETD_NOTRUNNING = 0,
|
||||
TELNETD_STARTED,
|
||||
TELNETD_RUNNING
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -107,124 +84,44 @@ int nsh_telnetmain(int argc, FAR char *argv[])
|
||||
#ifndef CONFIG_NSH_DISABLE_TELNETSTART
|
||||
int nsh_telnetstart(sa_family_t family)
|
||||
{
|
||||
static enum telnetd_state_e state = TELNETD_NOTRUNNING;
|
||||
int ret = OK;
|
||||
FAR struct console_stdio_s *pstate = nsh_newconsole(false);
|
||||
int ret;
|
||||
|
||||
if (state == TELNETD_NOTRUNNING)
|
||||
{
|
||||
struct telnetd_config_s config;
|
||||
DEBUGASSERT(pstate != NULL);
|
||||
|
||||
/* There is a tiny race condition here if two tasks were to try to
|
||||
* start the Telnet daemon concurrently.
|
||||
*/
|
||||
/* Start the telnet daemon */
|
||||
|
||||
state = TELNETD_STARTED;
|
||||
|
||||
/* Configure the telnet daemon */
|
||||
|
||||
config.d_port = HTONS(CONFIG_NSH_TELNETD_PORT);
|
||||
config.d_priority = CONFIG_NSH_TELNETD_DAEMONPRIO;
|
||||
config.d_stacksize = CONFIG_NSH_TELNETD_DAEMONSTACKSIZE;
|
||||
config.t_priority = CONFIG_NSH_TELNETD_CLIENTPRIO;
|
||||
config.t_stacksize = CONFIG_NSH_TELNETD_CLIENTSTACKSIZE;
|
||||
config.t_entry = nsh_telnetmain;
|
||||
|
||||
/* Start the telnet daemon */
|
||||
|
||||
ninfo("Starting the Telnet daemon\n");
|
||||
ninfo("Starting the Telnet daemon\n");
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if (family == AF_UNSPEC || family == AF_INET)
|
||||
{
|
||||
config.d_family = AF_INET;
|
||||
ret = telnetd_start(&config);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: Failed to start the Telnet IPv4 daemon: %d\n",
|
||||
ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = TELNETD_RUNNING;
|
||||
}
|
||||
}
|
||||
if (family == AF_INET)
|
||||
{
|
||||
char cmdline[] = CONFIG_SYSTEM_TELNETD_PROGNAME " -4 &";
|
||||
ret = nsh_parse(&pstate->cn_vtbl, cmdline);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (family == AF_UNSPEC || family == AF_INET6)
|
||||
{
|
||||
config.d_family = AF_INET6;
|
||||
ret = telnetd_start(&config);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: Failed to start the Telnet IPv6 daemon: %d\n",
|
||||
ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = TELNETD_RUNNING;
|
||||
}
|
||||
}
|
||||
if (family == AF_INET6)
|
||||
{
|
||||
char cmdline[] = CONFIG_SYSTEM_TELNETD_PROGNAME " -6 &";
|
||||
ret = nsh_parse(&pstate->cn_vtbl, cmdline);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (state == TELNETD_STARTED)
|
||||
{
|
||||
state = TELNETD_NOTRUNNING;
|
||||
}
|
||||
{
|
||||
char cmdline[] = CONFIG_SYSTEM_TELNETD_PROGNAME " &";
|
||||
ret = nsh_parse(&pstate->cn_vtbl, cmdline);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Failed to start the Telnet daemon: %d\n", ret);
|
||||
}
|
||||
|
||||
nsh_release(&pstate->cn_vtbl);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cmd_telnetd
|
||||
*
|
||||
* Description:
|
||||
* The Telnet daemon may be started either programmatically by calling
|
||||
* nsh_telnetstart() or it may be started from the NSH command line using
|
||||
* this telnetd command.
|
||||
*
|
||||
* This command would be suppressed with CONFIG_NSH_DISABLE_TELNETD
|
||||
* normally because the Telnet daemon is automatically started in
|
||||
* nsh_main.c. The exception is when CONFIG_NETINIT_NETLOCAL is selected.
|
||||
* IN that case, the network is not enabled at initialization but rather
|
||||
* must be enabled from the NSH command line or via other applications.
|
||||
*
|
||||
* In that case, calling nsh_telnetstart() before the the network is
|
||||
* initialized will fail.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None. All of the properties of the Telnet daemon are controlled by
|
||||
* NuttX configuration setting.
|
||||
*
|
||||
* Returned Values:
|
||||
* OK is returned on success; ERROR is return on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLE_TELNETD
|
||||
int cmd_telnetd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
||||
{
|
||||
UNUSED(vtbl);
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
|
||||
sa_family_t family = AF_UNSPEC;
|
||||
|
||||
/* If both IPv6 and IPv4 are enabled, then the address family must
|
||||
* be specified on the command line.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||
if (argc >= 2)
|
||||
{
|
||||
family = (strcmp(argv[1], "ipv6") == 0) ? AF_INET6 : AF_INET;
|
||||
}
|
||||
#endif
|
||||
|
||||
return nsh_telnetstart(family) < 0 ? ERROR : OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_NSH_TELNET */
|
||||
|
@ -77,8 +77,8 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NSH_TELNETD_PORT
|
||||
# define DEFAULT_PORT CONFIG_NSH_TELNETD_PORT
|
||||
#ifdef CONFIG_SYSTEM_TELNETD_PORT
|
||||
# define DEFAULT_PORT CONFIG_SYSTEM_TELNETD_PORT
|
||||
#else
|
||||
# define DEFAULT_PORT 23
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
config SYSTEM_TELNETD
|
||||
tristate "Telnet daemon application"
|
||||
default n
|
||||
default !DEFAULT_SMALL
|
||||
depends on NETUTILS_TELNETD
|
||||
---help---
|
||||
Enable the Telnet daemon application
|
||||
@ -28,6 +28,13 @@ config SYSTEM_TELNETD_STACKSIZE
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
depends on SYSTEM_TELNETD
|
||||
|
||||
config SYSTEM_TELNETD_PORT
|
||||
int "Telnetd port number"
|
||||
default 23
|
||||
---help---
|
||||
The telnet daemon will listen on this TCP port number for connections.
|
||||
Default: 23
|
||||
|
||||
config SYSTEM_TELNETD_SESSION_PRIORITY
|
||||
int "Telnetd session task priority"
|
||||
default 100
|
||||
|
@ -24,10 +24,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "netutils/telnetd.h"
|
||||
#include "netutils/netlib.h"
|
||||
#include "nshlib/nshlib.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -36,26 +38,62 @@
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
FAR char *argv1[3];
|
||||
char arg0[sizeof("0x1234567812345678")];
|
||||
struct telnetd_s daemon;
|
||||
FAR char *argv_[] =
|
||||
{
|
||||
CONFIG_SYSTEM_TELNETD_PROGNAME,
|
||||
"-c",
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Initialize the daemon structure */
|
||||
struct telnetd_config_s config =
|
||||
{
|
||||
HTONS(CONFIG_SYSTEM_TELNETD_PORT),
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
AF_INET,
|
||||
#else
|
||||
AF_INET6,
|
||||
#endif
|
||||
CONFIG_SYSTEM_TELNETD_SESSION_PRIORITY,
|
||||
CONFIG_SYSTEM_TELNETD_SESSION_STACKSIZE,
|
||||
#ifndef CONFIG_BUILD_KERNEL
|
||||
nsh_telnetmain,
|
||||
#endif
|
||||
#ifdef CONFIG_LIBC_EXECFUNCS
|
||||
CONFIG_SYSTEM_TELNETD_PROGNAME,
|
||||
#endif
|
||||
argv_,
|
||||
};
|
||||
|
||||
daemon.port = HTONS(23);
|
||||
daemon.family = AF_INET;
|
||||
daemon.entry = nsh_telnetmain;
|
||||
int daemon = 1;
|
||||
int opt;
|
||||
|
||||
/* NOTE: Settings for telnet session task */
|
||||
while ((opt = getopt(argc, argv, "46cp:")) != ERROR)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
case '4':
|
||||
config.d_family = AF_INET;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
case '6':
|
||||
config.d_family = AF_INET6;
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
daemon = 0;
|
||||
break;
|
||||
|
||||
daemon.priority = CONFIG_SYSTEM_TELNETD_SESSION_PRIORITY;
|
||||
daemon.stacksize = CONFIG_SYSTEM_TELNETD_SESSION_STACKSIZE;
|
||||
case 'p':
|
||||
config.d_port = atoi(optarg);
|
||||
break;
|
||||
|
||||
snprintf(arg0, sizeof(arg0), "0x%" PRIxPTR, (uintptr_t)&daemon);
|
||||
argv1[0] = "telnetd";
|
||||
argv1[1] = arg0;
|
||||
argv1[2] = NULL;
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [-4|-6] [-p port]\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
telnetd_daemon(2, argv1);
|
||||
return 0;
|
||||
return daemon ? telnetd_daemon(&config) : nsh_telnetmain(1, argv);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user