diff --git a/examples/cc3000/shell.c b/examples/cc3000/shell.c index aa45973f3..a1d8deb9b 100644 --- a/examples/cc3000/shell.c +++ b/examples/cc3000/shell.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/examples/cc3000/shell.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * This is a leverage of similar logic from uIP: @@ -217,6 +217,7 @@ int shell_main(int argc, char *argv[]) /* Configure the telnet daemon */ 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; diff --git a/examples/nsh/nsh_main.c b/examples/nsh/nsh_main.c index f55160c58..32ea17ae5 100644 --- a/examples/nsh/nsh_main.c +++ b/examples/nsh/nsh_main.c @@ -73,6 +73,16 @@ # undef CONFIG_NSH_TELNET #endif +/* If Telnet is used and both IPv6 and IPv4 are enabled, then we need to + * pick one. + */ + +#ifdef CONFIG_NET_IPv6 +# define ADDR_FAMILY AF_INET6 +#else +# define ADDR_FAMILY AF_INET +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -160,7 +170,7 @@ int nsh_main(int argc, char *argv[]) */ #if defined(CONFIG_NSH_TELNET) && !defined(CONFIG_NSH_NETLOCAL) - ret = nsh_telnetstart(); + ret = nsh_telnetstart(ADDR_FAMILY); if (ret < 0) { /* The daemon is NOT running. Report the error then fail... diff --git a/examples/nxterm/nxterm_main.c b/examples/nxterm/nxterm_main.c index cd06a82b4..6f211135f 100644 --- a/examples/nxterm/nxterm_main.c +++ b/examples/nxterm/nxterm_main.c @@ -71,6 +71,26 @@ #include "nxterm_internal.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The NSH telnet console requires networking support (and TCP/IP) */ + +#ifndef CONFIG_NET +# undef CONFIG_NSH_TELNET +#endif + +/* If Telnet is used and both IPv6 and IPv4 are enabled, then we need to + * pick one. + */ + +#ifdef CONFIG_NET_IPv6 +# define ADDR_FAMILY AF_INET6 +#else +# define ADDR_FAMILY AF_INET +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -234,7 +254,7 @@ int nxterm_main(int argc, char **argv) */ #ifdef CONFIG_NSH_TELNET - ret = nsh_telnetstart(); + ret = nsh_telnetstart(ADDR_FAMILY); if (ret < 0) { /* The daemon is NOT running. Report the error then fail... diff --git a/examples/telnetd/telnetd.c b/examples/telnetd/telnetd.c index 5bb5a4c56..cc03c70f4 100644 --- a/examples/telnetd/telnetd.c +++ b/examples/telnetd/telnetd.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/telnetd/telnetd.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * This is a leverage of similar logic from uIP: @@ -53,10 +53,6 @@ #include "telnetd.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Private Types ****************************************************************************/ @@ -247,6 +243,7 @@ int telnetd_main(int argc, char *argv[]) /* Configure the telnet daemon */ 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; diff --git a/include/netutils/telnetd.h b/include/netutils/telnetd.h index 1a4000d24..1e385d670 100644 --- a/include/netutils/telnetd.h +++ b/include/netutils/telnetd.h @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/netutils/telnetd.h * - * Copyright (C) 2007, 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -61,18 +61,22 @@ struct telnetd_config_s { /* These fields describe the telnet daemon */ - int d_port; /* The port to listen on (in network byte order) */ - int d_priority; /* The execution priority of the Telnet daemon task */ - int d_stacksize; /* The stack size needed by the Telnet daemon task */ + 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 */ /* These fields describe the priority of each thread created by the Telnet * daemon. */ - int t_priority; /* The execution priority of the spawned task, */ - int 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 */ + main_t t_entry; /* The entrypoint of the task to spawn when a new + * connection is accepted. */ }; /**************************************************************************** diff --git a/include/nshlib/nshlib.h b/include/nshlib/nshlib.h index 109664956..6a8b07612 100644 --- a/include/nshlib/nshlib.h +++ b/include/nshlib/nshlib.h @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/nshlib/nshlib.h * - * Copyright (C) 2011, 2013, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -147,8 +147,12 @@ int nsh_consolemain(int argc, char *argv[]); * the daemon has been started. * * Input Parameters: - * None. All of the properties of the Telnet daemon are controlled by - * NuttX configuration setting. + * family - Provides the IP family to use by the server. May be either + * AF_INET or AF_INET6. This is needed because both both may be + * enabled in the configuration. + * + * All of the other properties of the Telnet daemon are controlled by + * NuttX configuration settings. * * Returned Values: * The task ID of the Telnet daemon was successfully started. A negated @@ -156,7 +160,7 @@ int nsh_consolemain(int argc, char *argv[]); * ****************************************************************************/ -int nsh_telnetstart(void); +int nsh_telnetstart(sa_family_t family); /**************************************************************************** * Name: platform_motd diff --git a/netutils/telnetd/telnetd_daemon.c b/netutils/telnetd/telnetd_daemon.c index 2e140b712..c8aabf263 100644 --- a/netutils/telnetd/telnetd_daemon.c +++ b/netutils/telnetd/telnetd_daemon.c @@ -1,7 +1,7 @@ /**************************************************************************** * netutils/telnetd/telnetd_daemon.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -72,9 +73,10 @@ struct telnetd_s { - int port; /* The port to listen on (in network byte order) */ - int priority; /* The execution priority of the spawned task, */ - int stacksize; /* The stack size needed by the spawned task */ + 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. */ }; @@ -126,7 +128,16 @@ static struct telnetd_common_s g_telnetdcommon; static int telnetd_daemon(int argc, char *argv[]) { FAR struct telnetd_s *daemon; - struct sockaddr_in myaddr; + union + { + struct sockaddr generic; +#ifdef CONFIG_NET_IPv4 + struct sockaddr_in ipv4; +#endif +#ifdef CONFIG_NET_IPv6 + struct sockaddr_in6 ipv6; +#endif + } addr; struct telnet_session_s session; #ifdef CONFIG_NET_SOLINGER struct linger ling; @@ -187,11 +198,12 @@ static int telnetd_daemon(int argc, char *argv[]) /* Create a new TCP socket to use to listen for connections */ - listensd = socket(PF_INET, SOCK_STREAM, 0); + listensd = socket(daemon->family, SOCK_STREAM, 0); if (listensd < 0) { int errval = errno; - nerr("ERROR: socket failure: %d\n", errval); + nerr("ERROR: socket() failed for family %u: %d\n", + daemon->family, errval); return -errval; } @@ -208,11 +220,33 @@ static int telnetd_daemon(int argc, char *argv[]) /* Bind the socket to a local address */ - myaddr.sin_family = AF_INET; - myaddr.sin_port = daemon->port; - myaddr.sin_addr.s_addr = INADDR_ANY; +#ifdef CONFIG_NET_IPv4 + if (daemon->family == AF_INET) + { + addr.ipv4.sin_family = AF_INET; + addr.ipv4.sin_port = daemon->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) + { + addr.ipv6.sin6_family = AF_INET6; + addr.ipv6.sin6_port = daemon->port; + addrlen = sizeof(struct sockaddr_in6); - if (bind(listensd, (struct sockaddr*)&myaddr, sizeof(struct sockaddr_in)) < 0) + memset(addr.ipv6.sin6_addr.s6_addr, 0, addrlen); + } + else +#endif + { + nerr("ERROR: Unsupported address family: %u", daemon->family); + goto errout_with_socket; + } + + if (bind(listensd, &addr.generic, addrlen) < 0) { nerr("ERROR: bind failure: %d\n", errno); goto errout_with_socket; @@ -240,8 +274,8 @@ static int telnetd_daemon(int argc, char *argv[]) { ninfo("Accepting connections on port %d\n", ntohs(daemon->port)); - addrlen = sizeof(struct sockaddr_in); - acceptsd = accept(listensd, (struct sockaddr*)&myaddr, &addrlen); + socklen_t accptlen = sizeof(addr); + acceptsd = accept(listensd, &addr.generic, &accptlen); if (acceptsd < 0) { /* Accept failed */ @@ -390,6 +424,7 @@ int telnetd_start(FAR struct telnetd_config_s *config) /* 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; diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 9bd8d36f5..b4e334e0f 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -473,8 +473,12 @@ static const struct cmdmap_s g_cmdmap[] = #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, "\"\"" }, diff --git a/nshlib/nsh_telnetd.c b/nshlib/nsh_telnetd.c index 2f290a204..ae65dda89 100644 --- a/nshlib/nsh_telnetd.c +++ b/nshlib/nsh_telnetd.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -179,8 +180,12 @@ static int nsh_telnetmain(int argc, char *argv[]) * the daemon has been started. * * Input Parameters: - * None. All of the properties of the Telnet daemon are controlled by - * NuttX configuration setting. + * family - Provides the IP family to use by the server. May be either + * AF_INET or AF_INET6. This is needed because both both may be + * enabled in the configuration. + * + * All of the other properties of the Telnet daemon are controlled by + * NuttX configuration settings. * * Returned Values: * The task ID of the Telnet daemon was successfully started. A negated @@ -188,7 +193,7 @@ static int nsh_telnetmain(int argc, char *argv[]) * ****************************************************************************/ -int nsh_telnetstart(void) +int nsh_telnetstart(sa_family_t family) { static enum telnetd_state_e state = TELNETD_NOTRUNNING; int ret = OK; @@ -215,6 +220,7 @@ int nsh_telnetstart(void) /* Configure the telnet daemon */ config.d_port = HTONS(CONFIG_NSH_TELNETD_PORT); + config.d_family = family; config.d_priority = CONFIG_NSH_TELNETD_DAEMONPRIO; config.d_stacksize = CONFIG_NSH_TELNETD_DAEMONSTACKSIZE; config.t_priority = CONFIG_NSH_TELNETD_CLIENTPRIO; @@ -269,7 +275,21 @@ int nsh_telnetstart(void) #ifndef CONFIG_NSH_DISABLE_TELNETD int cmd_telnetd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { - return nsh_telnetstart() < 0 ? ERROR : OK; + sa_family_t family; + + /* If both IPv6 nd IPv4 are enabled, then the address family must + * be specified on the command line. + */ + +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + family = (strcmp(argv[1], "ipv6") == 0) ? AF_INET6 : AF_INET; +#elif defined(CONFIG_NET_IPv6) + family = AF_INET6; +#else /* if defined(CONFIG_NET_IPv4) */ + family = AF_INET; +#endif + + return nsh_telnetstart(family) < 0 ? ERROR : OK; } #endif