📄 nsh_telnetd.c
字号:
/**************************************************************************** * examples/nsh/nsh_telnetd.c * * Copyright (C) 2007 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * This is a leverage of similar logic from uIP: * * Author: Adam Dunkels <adam@sics.se> * Copyright (c) 2003, Adam Dunkels. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <nuttx/config.h>#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <pthread.h>#include <debug.h>#include <net/if.h>#include <net/uip/uip-lib.h>#include "nsh.h"/**************************************************************************** * Definitions ****************************************************************************/#define ISO_nl 0x0a#define ISO_cr 0x0d#define STATE_NORMAL 0#define STATE_IAC 1#define STATE_WILL 2#define STATE_WONT 3#define STATE_DO 4#define STATE_DONT 5#define STATE_CLOSE 6#define TELNET_IAC 255#define TELNET_WILL 251#define TELNET_WONT 252#define TELNET_DO 253#define TELNET_DONT 254/* Configurable settings */#ifndef CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE# define CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE 512#endif#ifndef CONFIG_EXAMPLES_NSH_CMD_SIZE# define CONFIG_EXAMPLES_NSH_CMD_SIZE 40#endif/* As threads are created to handle each request, a stack must be allocated * for the thread. Use a default if the user provided no stacksize. */#ifndef CONFIG_EXAMPLES_NSH_STACKSIZE# define CONFIG_EXAMPLES_NSH_STACKSIZE 4096#endif/* Enabled dumping of all input/output buffers */#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER/* Sizing */#define NSH_MAX_LINELEN 80/**************************************************************************** * Private Types ****************************************************************************/struct telnetd_s{ int tn_sockfd; uint16 tn_sndlen; uint8 tn_bufndx; uint8 tn_state; char tn_iobuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE]; char tn_cmd[CONFIG_EXAMPLES_NSH_CMD_SIZE];};/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: nsh_dumpbuffer * * Description: * Dump a buffer of data (debug only) * ****************************************************************************/#ifdef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFERstatic void nsh_dumpbuffer(const char *msg, const char *buffer, ssize_t nbytes){#ifdef CONFIG_DEBUG char line[128]; int ch; int i; int j; dbg("%s:\n", msg); for (i = 0; i < nbytes; i += 16) { sprintf(line, "%04x: ", i); for ( j = 0; j < 16; j++) { if (i + j < nbytes) { sprintf(&line[strlen(line)], "%02x ", buffer[i+j] ); } else { strcpy(&line[strlen(line)], " "); } } for ( j = 0; j < 16; j++) { if (i + j < nbytes) { ch = buffer[i+j]; sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.'); } } dbg("%s\n", line); }#endif}#else# define nsh_dumpbuffer(msg,buffer,nbytes)#endif/**************************************************************************** * Name: nsh_putchar * * Description: * Add another parsed character to the TELNET command string * ****************************************************************************/static void nsh_putchar(struct telnetd_s *pstate, uint8 ch){ /* Ignore carriage returns */ if (ch == ISO_cr) { return; } /* Add all other characters to the cmd buffer */ pstate->tn_cmd[pstate->tn_bufndx] = ch; /* If a newline was added or if the buffer is full, then process it now */ if (ch == ISO_nl || pstate->tn_bufndx == (CONFIG_EXAMPLES_NSH_CMD_SIZE - 1)) { if (pstate->tn_bufndx > 0) { pstate->tn_cmd[pstate->tn_bufndx] = '\0'; } nsh_dumpbuffer("TELNET CMD", pstate->tn_cmd, strlen(pstate->tn_cmd)); nsh_parse((void*)pstate, pstate->tn_cmd); pstate->tn_bufndx = 0; } else { pstate->tn_bufndx++; vdbg("Add '%c', bufndx=%d\n", ch, pstate->tn_bufndx); }}/**************************************************************************** * Name: nsh_sendopt * * Description: * ****************************************************************************/static void nsh_sendopt(struct telnetd_s *pstate, uint8 option, uint8 value){ uint8 optbuf[4]; optbuf[0] = TELNET_IAC; optbuf[1] = option; optbuf[2] = value; optbuf[3] = 0; nsh_dumpbuffer("Send optbuf", optbuf, 4); if (send(pstate->tn_sockfd, optbuf, 4, 0) < 0) { dbg("[%d] Failed to send TELNET_IAC\n", pstate->tn_sockfd); }}/**************************************************************************** * Name: nsh_flush * * Description: * Dump the buffered output info. * ****************************************************************************/static void nsh_flush(FAR struct telnetd_s *pstate){ if (pstate->tn_sndlen > 0) { nsh_dumpbuffer("Shell output", pstate->tn_iobuffer, pstate->tn_sndlen); if (send(pstate->tn_sockfd, pstate->tn_iobuffer, pstate->tn_sndlen, 0) < 0) { dbg("[%d] Failed to send response\n", pstate->tn_sockfd); } } pstate->tn_sndlen = 0;}/**************************************************************************** * Name: nsh_receive * * Description: * Process a received TELENET buffer * ****************************************************************************/static int nsh_receive(struct telnetd_s *pstate, size_t len){ char *ptr = pstate->tn_iobuffer; uint8 ch; while (len > 0) { ch = *ptr++; len--; vdbg("ch=%02x state=%d\n", ch, pstate->tn_state); switch (pstate->tn_state) { case STATE_IAC: if (ch == TELNET_IAC) { nsh_putchar(pstate, ch); pstate->tn_state = STATE_NORMAL; } else { switch (ch) { case TELNET_WILL: pstate->tn_state = STATE_WILL; break; case TELNET_WONT: pstate->tn_state = STATE_WONT; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -