From bd520203a03ca023dcbc0c77a6af59c4dc4c3b9a Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 9 Aug 2001 22:06:51 +0000 Subject: 2001-08-09 Fernando-Ruiz Casas * Makefile.am, configure.in, rtems_servers/Makefile.am, rtems_servers/telnetd.c, rtems_servers/telnetd.h, rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h, wrapup/Makefile.am: - pty and telnetd have a new subdir rtems_telnetd to avoid the side effect when ftpd change. - the tcp/ip stats have been implemented into icmds.c and started when telnetd daemon is started. * rtems_servers/telnetd.c, rtems_servers/telnetd.h: Removed. * rtems_telnetd: New directory. * rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h: New files. --- cpukit/ftpd/Makefile.am | 2 +- cpukit/libnetworking/ChangeLog | 17 ++ cpukit/libnetworking/Makefile.am | 2 +- cpukit/libnetworking/wrapup/Makefile.am | 2 +- cpukit/telnetd/Makefile.am | 44 ++++ cpukit/telnetd/README | 28 +++ cpukit/telnetd/icmds.c | 48 ++++ cpukit/telnetd/pty.c | 408 ++++++++++++++++++++++++++++++++ cpukit/telnetd/pty.h | 63 +++++ cpukit/telnetd/telnetd.c | 132 +++++++++++ cpukit/telnetd/telnetd.h | 35 +++ 11 files changed, 778 insertions(+), 3 deletions(-) create mode 100644 cpukit/telnetd/Makefile.am create mode 100644 cpukit/telnetd/README create mode 100644 cpukit/telnetd/icmds.c create mode 100644 cpukit/telnetd/pty.c create mode 100644 cpukit/telnetd/pty.h create mode 100644 cpukit/telnetd/telnetd.c create mode 100644 cpukit/telnetd/telnetd.h (limited to 'cpukit') diff --git a/cpukit/ftpd/Makefile.am b/cpukit/ftpd/Makefile.am index 56d4f2118f..17ad1c5fcb 100644 --- a/cpukit/ftpd/Makefile.am +++ b/cpukit/ftpd/Makefile.am @@ -33,7 +33,7 @@ EXTRA_DIST = ftpd.c ftpd.h include_HEADERS = ftpd.h -include_rtems_HEADERS = telnetd.h +include_rtems_HEADERS = PREINSTALL_FILES += $(PROJECT_INCLUDE) \ $(include_HEADERS:%=$(PROJECT_INCLUDE)/%) \ diff --git a/cpukit/libnetworking/ChangeLog b/cpukit/libnetworking/ChangeLog index c8069dbcad..0a4aafde94 100644 --- a/cpukit/libnetworking/ChangeLog +++ b/cpukit/libnetworking/ChangeLog @@ -1,3 +1,20 @@ +2001-08-09 Fernando-Ruiz Casas + + * Makefile.am, configure.in, rtems_servers/Makefile.am, + rtems_servers/telnetd.c, rtems_servers/telnetd.h, + rtems_telnetd/Makefile.am, rtems_telnetd/README, rtems_telnetd/icmds.c, + rtems_telnetd/pty.c, rtems_telnetd/pty.h, rtems_telnetd/telnetd.c, + rtems_telnetd/telnetd.h, wrapup/Makefile.am: + - pty and telnetd have a new subdir rtems_telnetd to avoid + the side effect when ftpd change. + - the tcp/ip stats have been implemented into icmds.c and + started when telnetd daemon is started. + * rtems_servers/telnetd.c, rtems_servers/telnetd.h: Removed. + * rtems_telnetd: New directory. + * rtems_telnetd/Makefile.am, rtems_telnetd/README, + rtems_telnetd/icmds.c, rtems_telnetd/pty.c, rtems_telnetd/pty.h, + rtems_telnetd/telnetd.c, rtems_telnetd/telnetd.h: New files. + 2001-05-26 Ralf Corsepius * rtems_servers/Makefile.am: Deleted blank lines. diff --git a/cpukit/libnetworking/Makefile.am b/cpukit/libnetworking/Makefile.am index 57f87c7b5d..e8b24ae45b 100644 --- a/cpukit/libnetworking/Makefile.am +++ b/cpukit/libnetworking/Makefile.am @@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 ACLOCAL_AMFLAGS = -I ../../../aclocal SUBDIRS = arpa kern machine sys vm lib libc net netinet nfs rtems \ - rtems_servers pppd modem rtems_webserver wrapup + rtems_servers pppd modem rtems_telnetd rtems_webserver wrapup include_HEADERS = \ bpfilter.h loop.h netdb.h opt_ipfw.h opt_mrouting.h \ diff --git a/cpukit/libnetworking/wrapup/Makefile.am b/cpukit/libnetworking/wrapup/Makefile.am index 5c8135ace6..b221766dfa 100644 --- a/cpukit/libnetworking/wrapup/Makefile.am +++ b/cpukit/libnetworking/wrapup/Makefile.am @@ -8,7 +8,7 @@ if HAS_POSIX POSIX_PIECES = rtems_webserver endif -NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers pppd modem \ +NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers rtems_telnetd pppd modem \ $(POSIX_PIECES) OBJS = $(foreach piece, $(NET_O_PIECES), ../$(piece)/$(ARCH)/*.o) LIB = $(ARCH)/libnetworking.a diff --git a/cpukit/telnetd/Makefile.am b/cpukit/telnetd/Makefile.am new file mode 100644 index 0000000000..a5d0480722 --- /dev/null +++ b/cpukit/telnetd/Makefile.am @@ -0,0 +1,44 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +include_rtemsdir = $(includedir)/rtems + +LIBNAME = libtelnetd-tmp +LIB = $(ARCH)/$(LIBNAME).a + +C_FILES = pty.c telnetd.c icmds.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +include_rtems_HEADERS = pty.h telnetd.h + +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../automake/compile.am +include $(top_srcdir)/../../../automake/lib.am + +$(PROJECT_INCLUDE)/rtems: + @$(mkinstalldirs) $@ +$(PROJECT_INCLUDE)/rtems/%.h: %.h + $(INSTALL_DATA) $< $@ + +# +# (OPTIONAL) Add local stuff here using += +# + +$(LIB): $(OBJS) + $(make-library) + +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems \ + $(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%) + +all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB) + +.PRECIOUS: $(LIB) + +EXTRA_DIST = README pty.c telnetd.c pty.h icmds.c telnetd.h + +include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/telnetd/README b/cpukit/telnetd/README new file mode 100644 index 0000000000..0c964c412d --- /dev/null +++ b/cpukit/telnetd/README @@ -0,0 +1,28 @@ +# +# $Id$ +# + +Author: fernando.ruiz@ctv.es (correo@fernando-ruiz.com) + +This directory contains a telnetd server +primary features: + + + create a user shell pseudo-terminal task. + +This code has not been extensively tested. It is provided as a tool +for RTEMS users to open more shell tcp/ip pseudo-terminal. +Suggestions and comments are appreciated. + +Read libmisc/shell for more information. + +NOTES: + +1. OOB not yet implemented. Only a reduced negotiation is implemented. + +2. If you have tcp/ip inited you can start telnetd daemon. + You need register pseudo-terminals driver into device drivers table. + 16 ptyX termios device terminales are created into /dev/. + Calling rtems_initialize_telnetd() starts the daemon. + Enjoy it. + +FUTURE: diff --git a/cpukit/telnetd/icmds.c b/cpukit/telnetd/icmds.c new file mode 100644 index 0000000000..1ac6820f39 --- /dev/null +++ b/cpukit/telnetd/icmds.c @@ -0,0 +1,48 @@ +#include +#include +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_inet(int argc,char * argv[]) { + rtems_bsdnet_show_inet_routes (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_mbuf(int argc,char * argv[]) { + rtems_bsdnet_show_mbuf_stats (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_if(int argc,char * argv[]) { + rtems_bsdnet_show_if_stats (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_ip(int argc,char * argv[]) { + rtems_bsdnet_show_ip_stats (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_icmp(int argc,char * argv[]) { + rtems_bsdnet_show_icmp_stats (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_tcp(int argc,char * argv[]) { + rtems_bsdnet_show_tcp_stats (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +int main_udp(int argc,char * argv[]) { + rtems_bsdnet_show_udp_stats (); + return 0; +} +/*+++++++++++++++++++++++++++++++++++++++++++++*/ +void register_icmds(void) { + shell_add_cmd("inet" ,"net","inet routes" ,main_inet); + shell_add_cmd("mbuf" ,"net","mbuf stats" ,main_mbuf); + shell_add_cmd("if" ,"net","if stats" ,main_if ); + shell_add_cmd("ip" ,"net","ip stats" ,main_ip ); + shell_add_cmd("icmp" ,"net","icmp stats" ,main_icmp); + shell_add_cmd("tcp" ,"net","tcp stats" ,main_tcp ); + shell_add_cmd("udp" ,"net","udp stats" ,main_udp ); +} + diff --git a/cpukit/telnetd/pty.c b/cpukit/telnetd/pty.c new file mode 100644 index 0000000000..a18b286922 --- /dev/null +++ b/cpukit/telnetd/pty.c @@ -0,0 +1,408 @@ +/* + * /dev/ptyXX (A first version for pseudo-terminals) + * + * Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es) + * May 2001 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id$ + */ +/*-----------------------------------------*/ +#include +#include +#include +#include +#include +/*-----------------------------------------*/ +#include +#include +#include +#include +/*-----------------------------------------*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +/*-----------------------------------------*/ +#define printk printf +/*-----------------------------------------*/ +#define IAC_ESC 255 +#define IAC_DONT 254 +#define IAC_DO 253 +#define IAC_WONT 252 +#define IAC_WILL 251 +#define IAC_SB 250 +#define IAC_GA 249 +#define IAC_EL 248 +#define IAC_EC 247 +#define IAC_AYT 246 +#define IAC_AO 245 +#define IAC_IP 244 +#define IAC_BRK 243 +#define IAC_DMARK 242 +#define IAC_NOP 241 +#define IAC_SE 240 +#define IAC_EOR 239 + +struct pty_tt; +typedef struct pty_tt pty_t; + +struct pty_tt { + char *devname; + struct rtems_termios_tty *ttyp; + tcflag_t c_cflag; + int opened; + int socket; + + int last_cr; + int iac_mode; +}; + + +int ptys_initted=FALSE; +pty_t ptys[MAX_PTYS]; + +/* This procedure returns the devname for a pty slot free. + * If not slot availiable (field socket>=0) + * then the socket argument is closed + */ + +char * get_pty(int socket) { + int ndx; + if (!ptys_initted) return NULL; + for (ndx=0;ndxc_cflag; + } else { + return -1; + }; + return 0; +} +/*-----------------------------------------------------------*/ +static int +ptyPollInitialize(int major,int minor,void * arg) { + rtems_libio_open_close_args_t * args = arg; + struct termios t; + if (minoriop->data1; + t.c_cflag=B9600|CS8;/* termios default */ + return ptySetAttributes(minor,&t); + } else { + return -1; + }; +} +/*-----------------------------------------------------------*/ +static int +ptyShutdown(int major,int minor,void * arg) { + if (minor=0) close(ptys[minor].socket); + ptys[minor].socket=-1; + chown(ptys[minor].devname,2,0); + } else { + return -1; + }; + return 0; +} +/*-----------------------------------------------------------*/ +/* Write Characters into pty device */ +/*-----------------------------------------------------------*/ +static int +ptyPollWrite(int minor, const char * buf,int len) { + int count; + if (minor + +#ifndef MAX_PTYS +#define MAX_PTYS 16 +#endif + +char * get_pty(int socket); + +rtems_device_driver pty_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); +rtems_device_driver pty_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg); +rtems_device_driver pty_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg); +rtems_device_driver pty_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg); +rtems_device_driver pty_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg); +rtems_device_driver pty_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg); + + +#define PTY_DRIVER_TABLE_ENTRY \ + { pty_initialize , pty_open , pty_close , \ + pty_read , pty_write , pty_control } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/telnetd/telnetd.c b/cpukit/telnetd/telnetd.c new file mode 100644 index 0000000000..ce7c5c118d --- /dev/null +++ b/cpukit/telnetd/telnetd.c @@ -0,0 +1,132 @@ +/***********************************************************/ +/* + * + * The telnet DAEMON + * + * Author: 17,may 2001 + * + * WORK: fernando.ruiz@ctv.es + * HOME: correo@fernando-ruiz.com + * + * After start the net you can start this daemon. + * It uses the previously inited pseudo-terminales (pty.c) + * getting a new terminal with getpty(). This function + * gives a terminal name passing a opened socket like parameter. + * + * With register_telnetd() you add a new command in the shell to start + * this daemon interactively. (Login in /dev/console of course) + * + * Sorry but OOB is not still implemented. (This is the first version) + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/***********************************************************/ +rtems_id telnetd_task_id =0; +rtems_unsigned32 telnetd_stack_size =16384; +rtems_task_priority telnetd_task_priority=100; +/***********************************************************/ +rtems_task rtems_task_telnetd(rtems_task_argument task_argument) { + int des_socket, + acp_socket; + struct sockaddr_in srv; + char * devname; + int i=1; + int size_adr; + if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) { + perror("telnetd:socket"); + rtems_task_delete(RTEMS_SELF); + }; + setsockopt(des_socket,SOL_SOCKET,0,&i,sizeof(i)); + memset(&srv,0,sizeof(srv)); + srv.sin_family=AF_INET; + srv.sin_port=htons(23); + size_adr=sizeof(srv); + if ((bind(des_socket,(struct sockaddr *)&srv,size_adr))<0) { + perror("telnetd:bind"); + close(des_socket); + rtems_task_delete(RTEMS_SELF); + }; + if ((listen(des_socket,5))<0) { + perror("telnetd:listen"); + close(des_socket); + rtems_task_delete(RTEMS_SELF); + }; + do { + acp_socket=accept(des_socket,(struct sockaddr*)&srv,&size_adr); + if (acp_socket<0) { + perror("telnetd:accept"); + break; + }; + if ((devname = get_pty(acp_socket)) ) { + shell_init(&devname[5], + telnetd_stack_size, + telnetd_task_priority, + devname,B9600|CS8,FALSE); + } else { + close(acp_socket); + }; + } while(1); + close(des_socket); + rtems_task_delete(RTEMS_SELF); +} +/***********************************************************/ +int rtems_initialize_telnetd(void) { + void register_icmds(void); + rtems_status_code sc; + + register_icmds(); /* stats for tcp/ip */ + + if (telnetd_task_id ) return RTEMS_RESOURCE_IN_USE; + if (telnetd_stack_size<=0 ) telnetd_stack_size =16384; + if (telnetd_task_priority<=2) telnetd_task_priority=100; + sc=rtems_task_create(new_rtems_name("tlnd"), + 100,RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &telnetd_task_id); + if (sc!=RTEMS_SUCCESSFUL) { + rtems_error(sc,"creating task telnetd"); + return (int)sc; + }; + sc=rtems_task_start(telnetd_task_id, + rtems_task_telnetd, + (rtems_task_argument)NULL); + if (sc!=RTEMS_SUCCESSFUL) { + rtems_error(sc,"starting task telnetd"); + }; + return (int)sc; +} +/***********************************************************/ +int main_telnetd(int argc,char * argv[]) { + rtems_status_code sc; + if (telnetd_task_id) { + printf("ERROR:telnetd already started\n"); + return 1; + }; + if (argc>1) telnetd_stack_size =str2int(argv[1]); + if (argc>2) telnetd_task_priority=str2int(argv[2]); + sc=rtems_initialize_telnetd(); + if (sc!=RTEMS_SUCCESSFUL) return sc; + printf("rtems_telnetd() started with stacksize=%u,priority=%d\n", + telnetd_stack_size,telnetd_task_priority); + return 0; +} +/***********************************************************/ +int register_telnetd(void) { + shell_add_cmd("telnetd","telnet","telnetd [stacksize [tsk_priority]]",main_telnetd); + return 0; +} +/***********************************************************/ diff --git a/cpukit/telnetd/telnetd.h b/cpukit/telnetd/telnetd.h new file mode 100644 index 0000000000..1bb99ebc1b --- /dev/null +++ b/cpukit/telnetd/telnetd.h @@ -0,0 +1,35 @@ +/* + * (A first version for telnetd) + * + * Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es) + * May 2001 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * rtems_initialize_telnetd() starts the daemon. + * main_telnetd() is the main_proc for the command telnetd in the shell + * register_telnetd() add a new command in the shell to start + * interactively the telnetd daemon. + * + * $Id$ + */ + +#ifndef __TELNETD_H +#define __TELNETD_H + +#ifdef __cplusplus +extern "C" { +#endif + +int rtems_initialize_telnetd(void); +int main_telnetd(int argc,char * argv[]); +int register_telnetd(void); + +#ifdef __cplusplus +} +#endif + +#endif + -- cgit v1.2.3