📄 shell.c
字号:
/* * Copyright (c) 2001, Swedish Institute of Computer Science. * 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. * * This file is part of the lwIP TCP/IP stack. * * Author: Adam Dunkels <adam@sics.se> * * $Id: shell.c,v 1.4 2002/01/02 17:35:40 adam Exp $ */#include <string.h>#include <stdio.h>#include "lwip/mem.h"#include "lwip/debug.h"#include "lwip/def.h"#include "lwip/api.h"#include "lwip/stats.h"static unsigned char buffer[1024];struct command { struct netconn *conn; s8_t (* exec)(struct command *); u8_t nargs; char *args[10];};#include <stdio.h>#include <errno.h>#define ESUCCESS 0#define ESYNTAX -1#define ETOOFEW -2#define ETOOMANY -3#define ECLOSED -4#define NCONNS 10static struct netconn *conns[NCONNS];static char help_msg[] = "Avaliable commands:\n\open [IP address] [TCP port]: opens a TCP connection to the specified address.\n\lstn [TCP port]: sets up a server on the specified port.\n\acpt [connection #]: waits for an incoming connection request.\n\send [connection #] [message]: sends a message on a TCP connection.\n\udpc [local UDP port] [IP address] [remote port]: opens a UDP \"connection\".\n\udpl [local UDP port] [IP address] [remote port]: opens a UDP-Lite \"connection\".\n\udpn [local UDP port] [IP address] [remote port]: opens a UDP \"connection\" without checksums.\n\udpb [local port] [remote port]: opens a UDP broadcast \"connection\".\n\usnd [connection #] [message]: sends a message on a UDP connection.\n\recv [connection #]: recieves data on a TCP or UDP connection.\n\clos [connection #]: closes a TCP or UDP connection.\n\stat: prints out lwIP statistics.\n\quit: quits.\n";static char *stat_msgs[] = { "Link level * transmitted ", " retransmitted ", " * received ", " forwarded ", " * dropped ", " * checksum errors ", " * length errors ", " * memory errors ", " routing errors ", " protocol errors ", " option errors ", " * misc errors ", " cache hits ", "IP * transmitted ", " retransmitted ", " * received ", " * forwarded ", " * dropped ", " * checksum errors ", " * length errors ", " * memory errors ", " * routing errors ", " * protocol errors ", " * option errors ", " * misc errors ", " cache hits ", "ICMP * transmitted ", " retransmitted ", " * received ", " forwarded ", " * dropped ", " * checksum errors ", " length errors ", " * memory errors ", " routing errors ", " * protocol errors ", " option errors ", " * misc errors ", " cache hits ", "UDP * transmitted ", " retransmitted ", " * received ", " forwarded ", " * dropped ", " * checksum errors ", " * length errors ", " * memory errors ", " * routing errors ", " * protocol errors ", " option errors ", " * misc errors ", " cache hits ", "TCP * transmitted ", " * retransmitted ", " * received ", " forwarded ", " * dropped ", " * checksum errors ", " * length errors ", " * memory errors ", " * routing errors ", " * protocol errors ", " * option errors ", " * misc errors ", " * cache hits ", "Pbufs * avaiable ", " * used ", " * high water mark ", " * errors ", " reclaimed ", " pbuf_alloc() locked ", " pbuf_refresh() locked ", "Memory * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "Memp PBUF * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "UDP PCB * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "TCP PCB * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "TCP LISTEN * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "TCP SEG * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "Netbufs * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "Netconns * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "API msgs * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "TCPIP msgs * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "Timeouts * avaliable ", " * used ", " * high water mark ", " * errors ", " * reclaimed ", "Semaphores * used ", " * high water mark ", " * errors ", "Mailboxes * used ", " * high water mark ", " * errors "};/*-----------------------------------------------------------------------------------*/static voidsendstr(const char *str, struct netconn *conn){ netconn_write(conn, (void *)str, strlen(str), NETCONN_NOCOPY);}/*-----------------------------------------------------------------------------------*/static s8_tcom_open(struct command *com){ struct ip_addr ipaddr; u16_t port; int i; err_t err; if(inet_aton(com->args[0], &ipaddr) == -1) { sendstr(strerror(errno), com->conn); return ESYNTAX; } port = strtol(com->args[1], NULL, 10); /* Find the first unused connection in conns. */ for(i = 0; i < NCONNS && conns[i] != NULL; i++); if(i == NCONNS) { sendstr("No more connections avaliable, sorry.\n", com->conn); return ESUCCESS; } sendstr("Opening connection to ", com->conn); netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); sendstr(":", com->conn); netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY); sendstr("\n", com->conn); conns[i] = netconn_new(NETCONN_TCP); if(conns[i] == NULL) { sendstr("Could not create connection identifier (out of memory).\n", com->conn); return ESUCCESS; } err = netconn_connect(conns[i], &ipaddr, port); if(err != ERR_OK) { fprintf(stderr, "error %s\n", lwip_strerr(err)); sendstr("Could not connect to remote host: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(err), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); netconn_delete(conns[i]); conns[i] = NULL; return ESUCCESS; } sendstr("Opened connection, connection identifier is ", com->conn); sprintf(buffer, "%d\n", i); netconn_write(com->conn, buffer, strlen(buffer), NETCONN_COPY); return ESUCCESS;}/*-----------------------------------------------------------------------------------*/static s8_tcom_lstn(struct command *com){ u16_t port; int i; err_t err; port = strtol(com->args[0], NULL, 10); /* Find the first unused connection in conns. */ for(i = 0; i < NCONNS && conns[i] != NULL; i++); if(i == NCONNS) { sendstr("No more connections avaliable, sorry.\n", com->conn); return ESUCCESS; } sendstr("Opening a listening connection on port ", com->conn); netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); sendstr("\n", com->conn); conns[i] = netconn_new(NETCONN_TCP); if(conns[i] == NULL) { sendstr("Could not create connection identifier (out of memory).\n", com->conn); return ESUCCESS; } err = netconn_bind(conns[i], IP_ADDR_ANY, port); if(err != ERR_OK) { netconn_delete(conns[i]); conns[i] = NULL; sendstr("Could not bind: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(err), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); return ESUCCESS; } err = netconn_listen(conns[i]); if(err != ERR_OK) { netconn_delete(conns[i]); conns[i] = NULL; sendstr("Could not listen: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(err), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); return ESUCCESS; } sendstr("Opened connection, connection identifier is ", com->conn); sprintf(buffer, "%d\n", i); netconn_write(com->conn, buffer, strlen(buffer), NETCONN_COPY); return ESUCCESS;}/*-----------------------------------------------------------------------------------*//*-----------------------------------------------------------------------------------*/static s8_tcom_clos(struct command *com){ int i; err_t err; i = strtol(com->args[0], NULL, 10); if(i > NCONNS) { sendstr("Connection identifier too high.\n", com->conn); return ESUCCESS; } if(conns[i] == NULL) { sendstr("Connection identifier not in use.\n", com->conn); return ESUCCESS; } err = netconn_close(conns[i]); if(err != ERR_OK) { sendstr("Could not close connection: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(err), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); return ESUCCESS; } sendstr("Connection closed.\n", com->conn); netconn_delete(conns[i]); conns[i] = NULL; return ESUCCESS;}/*-----------------------------------------------------------------------------------*/static s8_tcom_acpt(struct command *com){ int i, j; /* Find the first unused connection in conns. */ for(j = 0; j < NCONNS && conns[j] != NULL; j++); if(j == NCONNS) { sendstr("No more connections avaliable, sorry.\n", com->conn); return ESUCCESS; } i = strtol(com->args[0], NULL, 10); if(i > NCONNS) { sendstr("Connection identifier too high.\n", com->conn); return ESUCCESS; } if(conns[i] == NULL) { sendstr("Connection identifier not in use.\n", com->conn); return ESUCCESS; } conns[j] = netconn_accept(conns[i]); if(conns[j] == NULL) { sendstr("Could not accept connection: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(netconn_err(conns[i])), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); return ESUCCESS; } sendstr("Accepted connection, connection identifier for new connection is ", com->conn); sprintf(buffer, "%d\n", j); netconn_write(com->conn, buffer, strlen(buffer), NETCONN_COPY); return ESUCCESS;}/*-----------------------------------------------------------------------------------*/static s8_tcom_stat(struct command *com){ int i; char buf[100]; u16_t len; for(i = 0; i < sizeof(struct stats_) / 2; i++) { len = sprintf(buf, "%d", ((u16_t *)&stats)[i]); sendstr(stat_msgs[i], com->conn); netconn_write(com->conn, buf, len, NETCONN_COPY); sendstr("\n", com->conn); } return ESUCCESS;}/*-----------------------------------------------------------------------------------*/static s8_tcom_send(struct command *com){ int i; err_t err; int len; i = strtol(com->args[0], NULL, 10); if(i > NCONNS) { sendstr("Connection identifier too high.\n", com->conn); return ESUCCESS; } if(conns[i] == NULL) { sendstr("Connection identifier not in use.\n", com->conn); return ESUCCESS; } len = strlen(com->args[1]); com->args[1][len] = '\r'; com->args[1][len + 1] = '\n'; com->args[1][len + 2] = 0; err = netconn_write(conns[i], com->args[1], len + 3, NETCONN_COPY); if(err != ERR_OK) { sendstr("Could not send data: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(err), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); return ESUCCESS; } sendstr("Data enqueued for sending.\n", com->conn); return ESUCCESS;}/*-----------------------------------------------------------------------------------*/static s8_tcom_recv(struct command *com){ int i; err_t err; struct netbuf *buf; u16_t len; i = strtol(com->args[0], NULL, 10); if(i > NCONNS) { sendstr("Connection identifier too high.\n", com->conn); return ESUCCESS; } if(conns[i] == NULL) { sendstr("Connection identifier not in use.\n", com->conn); return ESUCCESS; } buf = netconn_recv(conns[i]); if(buf != NULL) { netbuf_copy(buf, buffer, 1024); len = netbuf_len(buf); sendstr("Reading from connection:\n", com->conn); netconn_write(com->conn, buffer, len, NETCONN_COPY); netbuf_delete(buf); } else { sendstr("EOF.\n", com->conn); } err = netconn_err(conns[i]); if(err != ERR_OK) { sendstr("Could not receive data: ", com->conn);#ifdef LWIP_DEBUG sendstr(lwip_strerr(err), com->conn);#else sendstr("(debugging must be turned on for error message to appear)", com->conn);#endif /* LWIP_DEBUG */ sendstr("\n", com->conn); return ESUCCESS; } return ESUCCESS;}/*-----------------------------------------------------------------------------------*/static s8_tcom_udpc(struct command *com){ struct ip_addr ipaddr; u16_t lport, rport; int i; err_t err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -