📄 telnetd.c
字号:
#include <stdio.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <socket.h>#include <in.h>#include <vxWorks.h>#include <taskLib.h>#include <rngLib.h>#include <ioLib.h>#include <sockLib.h>#include <inetLib.h>#include <selectLib.h>#include <net/protosw.h>#include <netinet/tcp_timer.h>#include "error/error.h"#include "tools/tools.h"#include "telnetd.h"/* support up/down key in tcl shell */#define ASCII_NUL 0x00 /* CTRL+@ */#define ASCII_SOH 0x01 /* CTRL+A */#define ASCII_STX 0x02 /* CTRL+B */#define ASCII_ETX 0x03 /* CTRL+C */#define ASCII_EOT 0x04 /* CTRL+D */#define ASCII_ENQ 0x05 /* CTRL+E */#define ASCII_ACK 0x06 /* CTRL+F */#define ASCII_BEL 0x07 /* CTRL+G */#define ASCII_BS 0x08 /* CTRL+H */#define ASCII_HT 0x09 /* CTRL+I */#define ASCII_LF 0x0A /* CTRL+J */#define ASCII_VT 0x0B /* CTRL+K */#define ASCII_FF 0x0C /* CTRL+L */#define ASCII_CR 0x0D /* CTRL+M */#define ASCII_SO 0x0E /* CTRL+N */#define ASCII_SI 0x0F /* CTRL+O */#define ASCII_DLE 0x10 /* CTRL+P */#define ASCII_DC1 0x11 /* CTRL+Q */#define ASCII_DC2 0x12 /* CTRL+R */#define ASCII_DC3 0x13 /* CTRL+S */#define ASCII_DC4 0x14 /* CTRL+T */#define ASCII_NAK 0x15 /* CTRL+U */#define ASCII_SYN 0x16 /* CTRL+V */#define ASCII_ETB 0x17 /* CTRL+W */#define ASCII_CAN 0x18 /* CTRL+X */#define ASCII_EM 0x19 /* CTRL+Y */#define ASCII_SUB 0x1A /* CTRL+Z */#define ASCII_ESC 0x1B /* CTRL+[ */#define ASCII_FS 0x1C /* CTRL+\ */#define ASCII_GS 0x1D /* CTRL+] */#define ASCII_RS 0x1E /* CTRL+^ */#define ASCII_US 0x1F /* CTRL+_ */#define ASCII_SP 0x20 /* SPace */#define CLOSE_SOCKET_CMD 1static RING_ID backlog_ring_id = NULL;static const char *_pty_name = "/pty/telnetd.";static const char *mpty_name = "/pty/telnetd.M";static const char *spty_name = "/pty/telnetd.S";static const char *pipe_name = "/pipe/telnetd";static int alive = FALSE, ssock = ERROR;static int input_daemon_task(int, int, int, int, int, int, int, int, int, int);static int output_daemon_task(int, int, int, int, int, int, int, int, int, int);STATUStelnetd_init(int prio, int port, int drop_eof, int edit_cmd){ alive = FALSE; ssock = ERROR; if ((backlog_ring_id = rngCreate(4096)) == NULL) { return ERROR; } if (ptyDevCreate((char *)_pty_name, 1024, 1024) == ERROR) { return ERROR; } if (pipeDevCreate((char *)pipe_name, 32, sizeof(int)) == ERROR) { return ERROR; } if (taskSpawn("telnetd_in", prio, 0, (16 * 1024), (FUNCPTR)input_daemon_task, port, drop_eof, edit_cmd, 0, 0, 0, 0, 0, 0, 0) == ERROR) { return ERROR; } if (taskSpawn("telnetd_out", prio, 0, (16 * 1024), (FUNCPTR)output_daemon_task, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR) { return ERROR; } return OK;}STATUStelnetd_exit(int code){ int pipe, cmd = CLOSE_SOCKET_CMD; if (alive == FALSE) { return OK; } if ((pipe = open(pipe_name, O_WRONLY, 0)) == ERROR) { return ERROR; } if (write(pipe, (char *)&cmd, sizeof(cmd)) == ERROR) { close(pipe); return ERROR; } close(pipe); return OK;}const char *telnetd_name(void){ return (spty_name);}static intinput_daemon_task(int port, int drop_eof, int edit_cmd, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9){ int mpty, pipe, msock, ssize, skeep, rlen, fdout; struct sockaddr_in msin, ssin; char rbuf[512];#if 1 tcp_keepidle = (60 * PR_SLOWHZ); /* Time before keepalive probes begin */ tcp_keepintvl = (5 * PR_SLOWHZ); /* Time between keepalive probes (tcp_keepcnt = 8) */#endif alive = FALSE; mpty = ERROR; pipe = ERROR; msock = ERROR; ssock = ERROR; if (edit_cmd) { fdout = ioTaskStdGet(0, STD_OUT); } if ((mpty = open(mpty_name, O_WRONLY, 0)) == ERROR) { fprintf(stderr, "Master PTY device open failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if ((pipe = open(pipe_name, O_RDONLY, 0)) == ERROR) { fprintf(stderr, "Control pipe device open failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if ((msock = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) { fprintf(stderr, "Socket create failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } memset(&msin, 0, sizeof(msin)); msin.sin_family = AF_INET; msin.sin_port = htons(port); msin.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(msock, (struct sockaddr *)&msin, sizeof(msin)) == ERROR) { fprintf(stderr, "Socket bind failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if (listen(msock, 1) == ERROR) { fprintf(stderr, "Socket listen failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } while (1) {start: ssize = sizeof(ssin); memset(&ssin, 0, sizeof(ssin)); if ((ssock = accept(msock, (struct sockaddr *)&ssin, &ssize)) == ERROR) { fprintf(stderr, "Socket accept failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } skeep = 1; if (setsockopt(ssock, SOL_SOCKET, SO_KEEPALIVE, (char *)&skeep, sizeof(skeep)) == ERROR) { fprintf(stderr, "Socket set option failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if (ioctl(pipe, FIOFLUSH, 0) == ERROR) { fprintf(stderr, "Control pipe device flush failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } while ((rlen = rngBufGet(backlog_ring_id, rbuf, sizeof(rbuf))) > 0) { if (write(ssock, rbuf, rlen) == ERROR) { close(ssock); goto start; } } alive = TRUE; if (edit_cmd) { ioTaskStdSet(0, STD_OUT, ssock); readline_cmd_not_done = TRUE; readline_length = 0; readline_point = 0; readline_line[0] = '\0'; } while (1) { fd_set rdfs; FD_ZERO(&rdfs); FD_SET(pipe, &rdfs); FD_SET(ssock, &rdfs); if (select(FD_SETSIZE, &rdfs, NULL, NULL, NULL) == ERROR) { fprintf(stderr, "Select system call failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if (FD_ISSET(pipe, &rdfs)) { int cmd, closed = 0; if (read(pipe, (char *)&cmd, sizeof(cmd)) == ERROR) { fprintf(stderr, "Control pipe device read failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } switch (cmd) { case CLOSE_SOCKET_CMD: closed = 1; break; default: fprintf(stderr, "Invalid control command received, cmd = %d.\n", cmd); fflush(stderr); break; } if (closed) { break; } } if (FD_ISSET(ssock, &rdfs)) { if ((rlen = read(ssock, rbuf, sizeof(rbuf))) == ERROR) { break; } if (rlen == 0) { break; } if (drop_eof) { int i, n = 0; for (i = 0; i < rlen; i++) { /* * Drop EOF(End Of File) character because slave PTY device will be implicitly * closed when operates in line mode, and this may affect the task using slave * PTY device such as Tcl shell. */ if (rbuf[i] != ASCII_EOT) { rbuf[n++] = rbuf[i]; } } rlen = n; } if (rlen > 0) { if (edit_cmd) { int i; for (i = 0; i < rlen; i++) { if (readline_edit == readline_pass_on) { readline_edit = readline_edit_0; } (*readline_edit)(rbuf[i]); if (!readline_cmd_not_done) { if (readline_length > 0) { if (write(mpty, readline_line, readline_length) == ERROR) { fprintf(stderr, "Master PTY device write failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } } readline_cmd_not_done = TRUE; readline_length = 0; readline_point = 0; readline_line[0] = '\0'; } } } else { if (write(mpty, rbuf, rlen) == ERROR) { fprintf(stderr, "Master PTY device write failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } } } } } if (edit_cmd) { ioTaskStdSet(0, STD_OUT, fdout); } alive = FALSE; close(ssock); }panic: alive = FALSE; close(ssock); close(msock); close(pipe); close(mpty); if (edit_cmd) { ioTaskStdSet(0, STD_OUT, fdout); } taskSuspend(0);}static intoutput_daemon_task(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9){ int mpty, pipe; mpty = ERROR; pipe = ERROR; if ((mpty = open(mpty_name, O_RDONLY, 0)) == ERROR) { fprintf(stderr, "Master PTY device open failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if ((pipe = open(pipe_name, O_WRONLY, 0)) == ERROR) { fprintf(stderr, "Control pipe device open failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } while (1) { char rbuf[512]; int rlen; if ((rlen = read(mpty, rbuf, sizeof(rbuf))) == ERROR) { fprintf(stderr, "Master PTY device read failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } if (alive == TRUE) { if (write(ssock, rbuf, rlen) == ERROR) { int cmd = CLOSE_SOCKET_CMD; if (write(pipe, (char *)&cmd, sizeof(cmd)) == ERROR) { fprintf(stderr, "Control pipe device write failed, \"%s: %s\" !\n", error_mod2str(errno), error_num2str(errno)); fflush(stderr); goto panic; } alive = FALSE; } } else { if (rngFreeBytes(backlog_ring_id) < rlen) { rngFlush(backlog_ring_id); } rngBufPut(backlog_ring_id, rbuf, rlen); } }panic: close(pipe); close(mpty); taskSuspend(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -