1 /*
2 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25 * OF SUCH DAMAGE.
26 *
27 * This file is part of the lwIP TCP/IP stack.
28 *
29 * Author: Adam Dunkels <adam@sics.se>
30 *
31 */
32
33 #include "shell.h"
34
35 #include "lwip/opt.h"
36
37 #if LWIP_NETCONN && LWIP_TCP
38
39 #include <string.h>
40 #include <stdio.h>
41
42 #include "lwip/mem.h"
43 #include "lwip/debug.h"
44 #include "lwip/def.h"
45 #include "lwip/api.h"
46 #include "lwip/stats.h"
47
48 #if LWIP_SOCKET
49 #include "lwip/errno.h"
50 #include "lwip/if_api.h"
51 #endif
52
53 #ifdef WIN32
54 #define NEWLINE "\r\n"
55 #else /* WIN32 */
56 #define NEWLINE "\n"
57 #endif /* WIN32 */
58
59 /** Define this to 1 if you want to echo back all received characters
60 * (e.g. so they are displayed on a remote telnet)
61 */
62 #ifndef SHELL_ECHO
63 #define SHELL_ECHO 0
64 #endif
65
66 #define BUFSIZE 1024
67 static unsigned char buffer[BUFSIZE];
68
69 struct command {
70 struct netconn *conn;
71 s8_t (* exec)(struct command *);
72 u8_t nargs;
73 char *args[10];
74 };
75
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <limits.h>
79
80 #define ESUCCESS 0
81 #define ESYNTAX -1
82 #define ETOOFEW -2
83 #define ETOOMANY -3
84 #define ECLOSED -4
85
86 #define NCONNS 10
87 static struct netconn *conns[NCONNS];
88
89 /* help_msg is split into 3 strings to prevent exceeding the C89 maximum length of 509 per string */
90 static char help_msg1[] = "Available commands:"NEWLINE"\
91 open [IP address] [TCP port]: opens a TCP connection to the specified address."NEWLINE"\
92 lstn [TCP port]: sets up a server on the specified port."NEWLINE"\
93 acpt [connection #]: waits for an incoming connection request."NEWLINE"\
94 send [connection #] [message]: sends a message on a TCP connection."NEWLINE"\
95 udpc [local UDP port] [IP address] [remote port]: opens a UDP \"connection\"."NEWLINE"\
96 udpl [local UDP port] [IP address] [remote port]: opens a UDP-Lite \"connection\"."NEWLINE"";
97 static char help_msg2[] = "udpn [local UDP port] [IP address] [remote port]: opens a UDP \"connection\" without checksums."NEWLINE"\
98 udpb [local port] [remote port]: opens a UDP broadcast \"connection\"."NEWLINE"\
99 usnd [connection #] [message]: sends a message on a UDP connection."NEWLINE"\
100 recv [connection #]: receives data on a TCP or UDP connection."NEWLINE"\
101 clos [connection #]: closes a TCP or UDP connection."NEWLINE"\
102 stat: prints out lwIP statistics."NEWLINE"\
103 idxtoname [index]: outputs interface name from index."NEWLINE"\
104 nametoidx [name]: outputs interface index from name."NEWLINE;
105 static char help_msg3[] =
106 "gethostnm [name]: outputs IP address of host."NEWLINE"\
107 quit: quits"NEWLINE"";
108
109 #if LWIP_STATS
110 static char padding_10spaces[] = " ";
111
112 #define PROTOCOL_STATS (LINK_STATS && ETHARP_STATS && IPFRAG_STATS && IP_STATS && ICMP_STATS && UDP_STATS && TCP_STATS)
113
114 #if PROTOCOL_STATS
115 static const char* shell_stat_proto_names[] = {
116 #if LINK_STATS
117 "LINK ",
118 #endif
119 #if ETHARP_STATS
120 "ETHARP ",
121 #endif
122 #if IPFRAG_STATS
123 "IP_FRAG ",
124 #endif
125 #if IP_STATS
126 "IP ",
127 #endif
128 #if ICMP_STATS
129 "ICMP ",
130 #endif
131 #if UDP_STATS
132 "UDP ",
133 #endif
134 #if TCP_STATS
135 "TCP ",
136 #endif
137 "last"
138 };
139
140 static struct stats_proto* shell_stat_proto_stats[] = {
141 #if LINK_STATS
142 &lwip_stats.link,
143 #endif
144 #if ETHARP_STATS
145 &lwip_stats.etharp,
146 #endif
147 #if IPFRAG_STATS
148 &lwip_stats.ip_frag,
149 #endif
150 #if IP_STATS
151 &lwip_stats.ip,
152 #endif
153 #if ICMP_STATS
154 &lwip_stats.icmp,
155 #endif
156 #if UDP_STATS
157 &lwip_stats.udp,
158 #endif
159 #if TCP_STATS
160 &lwip_stats.tcp,
161 #endif
162 };
163 static const size_t num_protostats = sizeof(shell_stat_proto_stats)/sizeof(struct stats_proto*);
164
165 static const char *stat_msgs_proto[] = {
166 " * transmitted ",
167 " * received ",
168 " forwarded ",
169 " * dropped ",
170 " * checksum errors ",
171 " * length errors ",
172 " * memory errors ",
173 " routing errors ",
174 " protocol errors ",
175 " option errors ",
176 " * misc errors ",
177 " cache hits "
178 };
179 #endif /* PROTOCOL_STATS */
180 #endif /* LWIP_STATS */
181
182 /*-----------------------------------------------------------------------------------*/
183 static void
sendstr(const char * str,struct netconn * conn)184 sendstr(const char *str, struct netconn *conn)
185 {
186 netconn_write(conn, (const void *)str, strlen(str), NETCONN_NOCOPY);
187 }
188 /*-----------------------------------------------------------------------------------*/
189 static s8_t
com_open(struct command * com)190 com_open(struct command *com)
191 {
192 ip_addr_t ipaddr;
193 u16_t port;
194 int i;
195 err_t err;
196 long tmp;
197
198 if (ipaddr_aton(com->args[0], &ipaddr) == -1) {
199 sendstr(strerror(errno), com->conn);
200 return ESYNTAX;
201 }
202 tmp = strtol(com->args[1], NULL, 10);
203 if((tmp < 0) || (tmp > 0xffff)) {
204 sendstr("Invalid port number."NEWLINE, com->conn);
205 return ESUCCESS;
206 }
207 port = (u16_t)tmp;
208
209 /* Find the first unused connection in conns. */
210 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
211
212 if (i == NCONNS) {
213 sendstr("No more connections available, sorry."NEWLINE, com->conn);
214 return ESUCCESS;
215 }
216
217 sendstr("Opening connection to ", com->conn);
218 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
219 sendstr(":", com->conn);
220 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
221 sendstr(NEWLINE, com->conn);
222
223 conns[i] = netconn_new(NETCONN_TCP);
224 if (conns[i] == NULL) {
225 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
226 return ESUCCESS;
227 }
228 err = netconn_connect(conns[i], &ipaddr, port);
229 if (err != ERR_OK) {
230 fprintf(stderr, "error %s"NEWLINE, lwip_strerr(err));
231 sendstr("Could not connect to remote host: ", com->conn);
232 #ifdef LWIP_DEBUG
233 sendstr(lwip_strerr(err), com->conn);
234 #else
235 sendstr("(debugging must be turned on for error message to appear)", com->conn);
236 #endif /* LWIP_DEBUG */
237 sendstr(NEWLINE, com->conn);
238 netconn_delete(conns[i]);
239 conns[i] = NULL;
240 return ESUCCESS;
241 }
242
243 sendstr("Opened connection, connection identifier is ", com->conn);
244 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
245 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
246
247 return ESUCCESS;
248 }
249 /*-----------------------------------------------------------------------------------*/
250 static s8_t
com_lstn(struct command * com)251 com_lstn(struct command *com)
252 {
253 u16_t port;
254 int i;
255 err_t err;
256 long tmp;
257
258 tmp = strtol(com->args[0], NULL, 10);
259 if((tmp < 0) || (tmp > 0xffff)) {
260 sendstr("Invalid port number."NEWLINE, com->conn);
261 return ESUCCESS;
262 }
263 port = (u16_t)tmp;
264
265 /* Find the first unused connection in conns. */
266 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
267
268 if (i == NCONNS) {
269 sendstr("No more connections available, sorry."NEWLINE, com->conn);
270 return ESUCCESS;
271 }
272
273 sendstr("Opening a listening connection on port ", com->conn);
274 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
275 sendstr(NEWLINE, com->conn);
276
277 conns[i] = netconn_new(NETCONN_TCP);
278 if (conns[i] == NULL) {
279 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
280 return ESUCCESS;
281 }
282
283 err = netconn_bind(conns[i], IP_ADDR_ANY, port);
284 if (err != ERR_OK) {
285 netconn_delete(conns[i]);
286 conns[i] = NULL;
287 sendstr("Could not bind: ", com->conn);
288 #ifdef LWIP_DEBUG
289 sendstr(lwip_strerr(err), com->conn);
290 #else
291 sendstr("(debugging must be turned on for error message to appear)", com->conn);
292 #endif /* LWIP_DEBUG */
293 sendstr(NEWLINE, com->conn);
294 return ESUCCESS;
295 }
296
297 err = netconn_listen(conns[i]);
298 if (err != ERR_OK) {
299 netconn_delete(conns[i]);
300 conns[i] = NULL;
301 sendstr("Could not listen: ", com->conn);
302 #ifdef LWIP_DEBUG
303 sendstr(lwip_strerr(err), com->conn);
304 #else
305 sendstr("(debugging must be turned on for error message to appear)", com->conn);
306 #endif /* LWIP_DEBUG */
307 sendstr(NEWLINE, com->conn);
308 return ESUCCESS;
309 }
310
311 sendstr("Opened connection, connection identifier is ", com->conn);
312 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
313 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
314
315 return ESUCCESS;
316 }
317 /*-----------------------------------------------------------------------------------*/
318 /*-----------------------------------------------------------------------------------*/
319 static s8_t
com_clos(struct command * com)320 com_clos(struct command *com)
321 {
322 int i;
323 err_t err;
324
325 i = strtol(com->args[0], NULL, 10);
326
327 if (i > NCONNS) {
328 sendstr("Connection identifier too high."NEWLINE, com->conn);
329 return ESUCCESS;
330 }
331 if (conns[i] == NULL) {
332 sendstr("Connection identifier not in use."NEWLINE, com->conn);
333 return ESUCCESS;
334 }
335
336 err = netconn_close(conns[i]);
337 if (err != ERR_OK) {
338 sendstr("Could not close connection: ", com->conn);
339 #ifdef LWIP_DEBUG
340 sendstr(lwip_strerr(err), com->conn);
341 #else
342 sendstr("(debugging must be turned on for error message to appear)", com->conn);
343 #endif /* LWIP_DEBUG */
344 sendstr(NEWLINE, com->conn);
345 return ESUCCESS;
346 }
347
348 sendstr("Connection closed."NEWLINE, com->conn);
349 netconn_delete(conns[i]);
350 conns[i] = NULL;
351 return ESUCCESS;
352 }
353 /*-----------------------------------------------------------------------------------*/
354 static s8_t
com_acpt(struct command * com)355 com_acpt(struct command *com)
356 {
357 int i, j;
358 err_t err;
359
360 /* Find the first unused connection in conns. */
361 for(j = 0; j < NCONNS && conns[j] != NULL; j++);
362
363 if (j == NCONNS) {
364 sendstr("No more connections available, sorry."NEWLINE, com->conn);
365 return ESUCCESS;
366 }
367
368 i = strtol(com->args[0], NULL, 10);
369
370 if (i > NCONNS) {
371 sendstr("Connection identifier too high."NEWLINE, com->conn);
372 return ESUCCESS;
373 }
374 if (conns[i] == NULL) {
375 sendstr("Connection identifier not in use."NEWLINE, com->conn);
376 return ESUCCESS;
377 }
378
379 err = netconn_accept(conns[i], &conns[j]);
380
381 if (err != ERR_OK) {
382 sendstr("Could not accept connection: ", com->conn);
383 #ifdef LWIP_DEBUG
384 sendstr(lwip_strerr(err), com->conn);
385 #else
386 sendstr("(debugging must be turned on for error message to appear)", com->conn);
387 #endif /* LWIP_DEBUG */
388 sendstr(NEWLINE, com->conn);
389 return ESUCCESS;
390 }
391
392 sendstr("Accepted connection, connection identifier for new connection is ", com->conn);
393 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, j);
394 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
395
396 return ESUCCESS;
397 }
398 /*-----------------------------------------------------------------------------------*/
399 #if LWIP_STATS
400 static void
com_stat_write_mem(struct netconn * conn,struct stats_mem * elem,int i)401 com_stat_write_mem(struct netconn *conn, struct stats_mem *elem, int i)
402 {
403 u16_t len;
404 char buf[100];
405 size_t slen;
406
407 #ifdef LWIP_DEBUG
408 LWIP_UNUSED_ARG(i);
409 slen = strlen(elem->name);
410 netconn_write(conn, elem->name, slen, NETCONN_COPY);
411 #else /* LWIP_DEBUG */
412 len = (u16_t)sprintf(buf, "%d", i);
413 slen = strlen(buf);
414 netconn_write(conn, buf, slen, NETCONN_COPY);
415 #endif /* LWIP_DEBUG */
416 if(slen < 10) {
417 netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY);
418 }
419
420 len = (u16_t)sprintf(buf, " * available %"MEM_SIZE_F NEWLINE, elem->avail);
421 netconn_write(conn, buf, len, NETCONN_COPY);
422 len = (u16_t)sprintf(buf, " * used %"MEM_SIZE_F NEWLINE, elem->used);
423 netconn_write(conn, buf, len, NETCONN_COPY);
424 len = (u16_t)sprintf(buf, " * high water mark %"MEM_SIZE_F NEWLINE, elem->max);
425 netconn_write(conn, buf, len, NETCONN_COPY);
426 len = (u16_t)sprintf(buf, " * errors %"STAT_COUNTER_F NEWLINE, elem->err);
427 netconn_write(conn, buf, len, NETCONN_COPY);
428 len = (u16_t)sprintf(buf, " * illegal %"STAT_COUNTER_F NEWLINE, elem->illegal);
429 netconn_write(conn, buf, len, NETCONN_COPY);
430 }
431 static void
com_stat_write_sys(struct netconn * conn,struct stats_syselem * elem,const char * name)432 com_stat_write_sys(struct netconn *conn, struct stats_syselem *elem, const char *name)
433 {
434 u16_t len;
435 char buf[100];
436 size_t slen = strlen(name);
437
438 netconn_write(conn, name, slen, NETCONN_COPY);
439 if(slen < 10) {
440 netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY);
441 }
442
443 len = (u16_t)sprintf(buf, " * used %"STAT_COUNTER_F NEWLINE, elem->used);
444 netconn_write(conn, buf, len, NETCONN_COPY);
445 len = (u16_t)sprintf(buf, " * high water mark %"STAT_COUNTER_F NEWLINE, elem->max);
446 netconn_write(conn, buf, len, NETCONN_COPY);
447 len = (u16_t)sprintf(buf, " * errors %"STAT_COUNTER_F NEWLINE, elem->err);
448 netconn_write(conn, buf, len, NETCONN_COPY);
449 }
450 static s8_t
com_stat(struct command * com)451 com_stat(struct command *com)
452 {
453 #if PROTOCOL_STATS || MEMP_STATS
454 size_t i;
455 #endif /* PROTOCOL_STATS || MEMP_STATS */
456 #if PROTOCOL_STATS
457 size_t k;
458 char buf[100];
459 u16_t len;
460
461 /* protocol stats, @todo: add IGMP */
462 for(i = 0; i < num_protostats; i++) {
463 size_t s = sizeof(struct stats_proto)/sizeof(STAT_COUNTER);
464 STAT_COUNTER *c = &shell_stat_proto_stats[i]->xmit;
465 LWIP_ASSERT("stats not in sync", s == sizeof(stat_msgs_proto)/sizeof(char*));
466 netconn_write(com->conn, shell_stat_proto_names[i], strlen(shell_stat_proto_names[i]), NETCONN_COPY);
467 for(k = 0; k < s; k++) {
468 len = (u16_t)sprintf(buf, "%s%"STAT_COUNTER_F NEWLINE, stat_msgs_proto[k], c[k]);
469 netconn_write(com->conn, buf, len, NETCONN_COPY);
470 }
471 }
472 #endif /* PROTOCOL_STATS */
473 #if MEM_STATS
474 com_stat_write_mem(com->conn, &lwip_stats.mem, -1);
475 #endif /* MEM_STATS */
476 #if MEMP_STATS
477 for(i = 0; i < MEMP_MAX; i++) {
478 com_stat_write_mem(com->conn, lwip_stats.memp[i], -1);
479 }
480 #endif /* MEMP_STATS */
481 #if SYS_STATS
482 com_stat_write_sys(com->conn, &lwip_stats.sys.sem, "SEM ");
483 com_stat_write_sys(com->conn, &lwip_stats.sys.mutex, "MUTEX ");
484 com_stat_write_sys(com->conn, &lwip_stats.sys.mbox, "MBOX ");
485 #endif /* SYS_STATS */
486
487 return ESUCCESS;
488 }
489 #endif
490 /*-----------------------------------------------------------------------------------*/
491 static s8_t
com_send(struct command * com)492 com_send(struct command *com)
493 {
494 int i;
495 err_t err;
496 size_t len;
497
498 i = strtol(com->args[0], NULL, 10);
499
500 if (i > NCONNS) {
501 sendstr("Connection identifier too high."NEWLINE, com->conn);
502 return ESUCCESS;
503 }
504
505 if (conns[i] == NULL) {
506 sendstr("Connection identifier not in use."NEWLINE, com->conn);
507 return ESUCCESS;
508 }
509
510 len = strlen(com->args[1]);
511 com->args[1][len] = '\r';
512 com->args[1][len + 1] = '\n';
513 com->args[1][len + 2] = 0;
514
515 err = netconn_write(conns[i], com->args[1], len + 3, NETCONN_COPY);
516 if (err != ERR_OK) {
517 sendstr("Could not send data: ", com->conn);
518 #ifdef LWIP_DEBUG
519 sendstr(lwip_strerr(err), com->conn);
520 #else
521 sendstr("(debugging must be turned on for error message to appear)", com->conn);
522 #endif /* LWIP_DEBUG */
523 sendstr(NEWLINE, com->conn);
524 return ESUCCESS;
525 }
526
527 sendstr("Data enqueued for sending."NEWLINE, com->conn);
528 return ESUCCESS;
529 }
530 /*-----------------------------------------------------------------------------------*/
531 static s8_t
com_recv(struct command * com)532 com_recv(struct command *com)
533 {
534 int i;
535 err_t err;
536 struct netbuf *buf;
537 u16_t len;
538
539 i = strtol(com->args[0], NULL, 10);
540
541 if (i > NCONNS) {
542 sendstr("Connection identifier too high."NEWLINE, com->conn);
543 return ESUCCESS;
544 }
545
546 if (conns[i] == NULL) {
547 sendstr("Connection identifier not in use."NEWLINE, com->conn);
548 return ESUCCESS;
549 }
550
551 err = netconn_recv(conns[i], &buf);
552 if (err == ERR_OK) {
553
554 netbuf_copy(buf, buffer, BUFSIZE);
555 len = netbuf_len(buf);
556 sendstr("Reading from connection:"NEWLINE, com->conn);
557 netconn_write(com->conn, buffer, len, NETCONN_COPY);
558 netbuf_delete(buf);
559 } else {
560 sendstr("EOF."NEWLINE, com->conn);
561 }
562 err = netconn_err(conns[i]);
563 if (err != ERR_OK) {
564 sendstr("Could not receive data: ", com->conn);
565 #ifdef LWIP_DEBUG
566 sendstr(lwip_strerr(err), com->conn);
567 #else
568 sendstr("(debugging must be turned on for error message to appear)", com->conn);
569 #endif /* LWIP_DEBUG */
570 sendstr(NEWLINE, com->conn);
571 return ESUCCESS;
572 }
573 return ESUCCESS;
574 }
575 /*-----------------------------------------------------------------------------------*/
576 static s8_t
com_udpc(struct command * com)577 com_udpc(struct command *com)
578 {
579 ip_addr_t ipaddr;
580 u16_t lport, rport;
581 int i;
582 err_t err;
583 long tmp;
584
585 tmp = strtol(com->args[0], NULL, 10);
586 if((tmp < 0) || (tmp > 0xffff)) {
587 sendstr("Invalid port number."NEWLINE, com->conn);
588 return ESUCCESS;
589 }
590 lport = (u16_t)tmp;
591 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
592 sendstr(strerror(errno), com->conn);
593 return ESYNTAX;
594 }
595 tmp = strtol(com->args[2], NULL, 10);
596 if((tmp < 0) || (tmp > 0xffff)) {
597 sendstr("Invalid port number."NEWLINE, com->conn);
598 return ESUCCESS;
599 }
600 rport = (u16_t)tmp;
601
602 /* Find the first unused connection in conns. */
603 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
604
605 if (i == NCONNS) {
606 sendstr("No more connections available, sorry."NEWLINE, com->conn);
607 return ESUCCESS;
608 }
609
610 sendstr("Setting up UDP connection from port ", com->conn);
611 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
612 sendstr(" to ", com->conn);
613 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
614 sendstr(":", com->conn);
615 netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
616 sendstr(NEWLINE, com->conn);
617
618 conns[i] = netconn_new(NETCONN_UDP);
619 if (conns[i] == NULL) {
620 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
621 return ESUCCESS;
622 }
623
624 err = netconn_connect(conns[i], &ipaddr, rport);
625 if (err != ERR_OK) {
626 netconn_delete(conns[i]);
627 conns[i] = NULL;
628 sendstr("Could not connect to remote host: ", com->conn);
629 #ifdef LWIP_DEBUG
630 sendstr(lwip_strerr(err), com->conn);
631 #else
632 sendstr("(debugging must be turned on for error message to appear)", com->conn);
633 #endif /* LWIP_DEBUG */
634 sendstr(NEWLINE, com->conn);
635 return ESUCCESS;
636 }
637
638 err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
639 if (err != ERR_OK) {
640 netconn_delete(conns[i]);
641 conns[i] = NULL;
642 sendstr("Could not bind: ", com->conn);
643 #ifdef LWIP_DEBUG
644 sendstr(lwip_strerr(err), com->conn);
645 #else
646 sendstr("(debugging must be turned on for error message to appear)", com->conn);
647 #endif /* LWIP_DEBUG */
648 sendstr(NEWLINE, com->conn);
649 return ESUCCESS;
650 }
651
652 sendstr("Connection set up, connection identifier is ", com->conn);
653 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
654 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
655
656 return ESUCCESS;
657 }
658 /*-----------------------------------------------------------------------------------*/
659 static s8_t
com_udpl(struct command * com)660 com_udpl(struct command *com)
661 {
662 ip_addr_t ipaddr;
663 u16_t lport, rport;
664 int i;
665 err_t err;
666 long tmp;
667
668 tmp = strtol(com->args[0], NULL, 10);
669 if((tmp < 0) || (tmp > 0xffff)) {
670 sendstr("Invalid port number."NEWLINE, com->conn);
671 return ESUCCESS;
672 }
673 lport = (u16_t)tmp;
674 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
675 sendstr(strerror(errno), com->conn);
676 return ESYNTAX;
677 }
678 tmp = strtol(com->args[2], NULL, 10);
679 if((tmp < 0) || (tmp > 0xffff)) {
680 sendstr("Invalid port number."NEWLINE, com->conn);
681 return ESUCCESS;
682 }
683 rport = (u16_t)tmp;
684
685 /* Find the first unused connection in conns. */
686 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
687
688 if (i == NCONNS) {
689 sendstr("No more connections available, sorry."NEWLINE, com->conn);
690 return ESUCCESS;
691 }
692
693 sendstr("Setting up UDP-Lite connection from port ", com->conn);
694 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
695 sendstr(" to ", com->conn);
696 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
697 sendstr(":", com->conn);
698 netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
699 sendstr(NEWLINE, com->conn);
700
701 conns[i] = netconn_new(NETCONN_UDPLITE);
702 if (conns[i] == NULL) {
703 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
704 return ESUCCESS;
705 }
706
707 err = netconn_connect(conns[i], &ipaddr, rport);
708 if (err != ERR_OK) {
709 netconn_delete(conns[i]);
710 conns[i] = NULL;
711 sendstr("Could not connect to remote host: ", com->conn);
712 #ifdef LWIP_DEBUG
713 sendstr(lwip_strerr(err), com->conn);
714 #else
715 sendstr("(debugging must be turned on for error message to appear)", com->conn);
716 #endif /* LWIP_DEBUG */
717 sendstr(NEWLINE, com->conn);
718 return ESUCCESS;
719 }
720
721 err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
722 if (err != ERR_OK) {
723 netconn_delete(conns[i]);
724 conns[i] = NULL;
725 sendstr("Could not bind: ", com->conn);
726 #ifdef LWIP_DEBUG
727 sendstr(lwip_strerr(err), com->conn);
728 #else
729 sendstr("(debugging must be turned on for error message to appear)", com->conn);
730 #endif /* LWIP_DEBUG */
731 sendstr(NEWLINE, com->conn);
732 return ESUCCESS;
733 }
734
735 sendstr("Connection set up, connection identifier is ", com->conn);
736 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
737 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
738
739 return ESUCCESS;
740 }
741 /*-----------------------------------------------------------------------------------*/
742 static s8_t
com_udpn(struct command * com)743 com_udpn(struct command *com)
744 {
745 ip_addr_t ipaddr;
746 u16_t lport, rport;
747 int i;
748 err_t err;
749 long tmp;
750
751 tmp = strtol(com->args[0], NULL, 10);
752 if((tmp < 0) || (tmp > 0xffff)) {
753 sendstr("Invalid port number."NEWLINE, com->conn);
754 return ESUCCESS;
755 }
756 lport = (u16_t)tmp;
757 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
758 sendstr(strerror(errno), com->conn);
759 return ESYNTAX;
760 }
761 tmp = strtol(com->args[2], NULL, 10);
762 if((tmp < 0) || (tmp > 0xffff)) {
763 sendstr("Invalid port number."NEWLINE, com->conn);
764 return ESUCCESS;
765 }
766 rport = (u16_t)tmp;
767
768 /* Find the first unused connection in conns. */
769 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
770
771 if (i == NCONNS) {
772 sendstr("No more connections available, sorry."NEWLINE, com->conn);
773 return ESUCCESS;
774 }
775
776 sendstr("Setting up UDP connection without checksums from port ", com->conn);
777 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
778 sendstr(" to ", com->conn);
779 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
780 sendstr(":", com->conn);
781 netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
782 sendstr(NEWLINE, com->conn);
783
784 conns[i] = netconn_new(NETCONN_UDPNOCHKSUM);
785 if (conns[i] == NULL) {
786 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
787 return ESUCCESS;
788 }
789
790 err = netconn_connect(conns[i], &ipaddr, rport);
791 if (err != ERR_OK) {
792 netconn_delete(conns[i]);
793 conns[i] = NULL;
794 sendstr("Could not connect to remote host: ", com->conn);
795 #ifdef LWIP_DEBUG
796 sendstr(lwip_strerr(err), com->conn);
797 #else
798 sendstr("(debugging must be turned on for error message to appear)", com->conn);
799 #endif /* LWIP_DEBUG */
800 sendstr(NEWLINE, com->conn);
801 return ESUCCESS;
802 }
803
804 err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
805 if (err != ERR_OK) {
806 netconn_delete(conns[i]);
807 conns[i] = NULL;
808 sendstr("Could not bind: ", com->conn);
809 #ifdef LWIP_DEBUG
810 sendstr(lwip_strerr(err), com->conn);
811 #else
812 sendstr("(debugging must be turned on for error message to appear)", com->conn);
813 #endif /* LWIP_DEBUG */
814 sendstr(NEWLINE, com->conn);
815 return ESUCCESS;
816 }
817
818 sendstr("Connection set up, connection identifier is ", com->conn);
819 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
820 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
821
822 return ESUCCESS;
823 }
824 /*-----------------------------------------------------------------------------------*/
825 static s8_t
com_udpb(struct command * com)826 com_udpb(struct command *com)
827 {
828 ip_addr_t ipaddr;
829 #if LWIP_IPV4
830 u16_t lport;
831 #endif /* LWIP_IPV4 */
832 u16_t rport;
833 int i;
834 err_t err;
835 long tmp;
836
837 tmp = strtol(com->args[0], NULL, 10);
838 if((tmp < 0) || (tmp > 0xffff)) {
839 sendstr("Invalid port number."NEWLINE, com->conn);
840 return ESUCCESS;
841 }
842 #if LWIP_IPV4
843 lport = (u16_t)tmp;
844 #endif /* LWIP_IPV4 */
845 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
846 sendstr(strerror(errno), com->conn);
847 return ESYNTAX;
848 }
849 tmp = strtol(com->args[2], NULL, 10);
850 if((tmp < 0) || (tmp > 0xffff)) {
851 sendstr("Invalid port number."NEWLINE, com->conn);
852 return ESUCCESS;
853 }
854 rport = (u16_t)tmp;
855
856 /* Find the first unused connection in conns. */
857 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
858
859 if (i == NCONNS) {
860 sendstr("No more connections available, sorry."NEWLINE, com->conn);
861 return ESUCCESS;
862 }
863
864 sendstr("Setting up UDP broadcast connection from port ", com->conn);
865 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
866 sendstr(" to ", com->conn);
867 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
868 sendstr(NEWLINE, com->conn);
869
870 conns[i] = netconn_new(NETCONN_UDP);
871 if (conns[i] == NULL) {
872 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
873 return ESUCCESS;
874 }
875
876 err = netconn_connect(conns[i], &ipaddr, rport);
877 if (err != ERR_OK) {
878 netconn_delete(conns[i]);
879 conns[i] = NULL;
880 sendstr("Could not connect to remote host: ", com->conn);
881 #ifdef LWIP_DEBUG
882 sendstr(lwip_strerr(err), com->conn);
883 #else
884 sendstr("(debugging must be turned on for error message to appear)", com->conn);
885 #endif /* LWIP_DEBUG */
886 sendstr(NEWLINE, com->conn);
887 return ESUCCESS;
888 }
889
890 #if LWIP_IPV4
891 if (IP_IS_V6_VAL(ipaddr)) {
892 err = netconn_bind(conns[i], &ip_addr_broadcast, lport);
893 if (err != ERR_OK) {
894 netconn_delete(conns[i]);
895 conns[i] = NULL;
896 sendstr("Could not bind: ", com->conn);
897 #ifdef LWIP_DEBUG
898 sendstr(lwip_strerr(err), com->conn);
899 #else
900 sendstr("(debugging must be turned on for error message to appear)", com->conn);
901 #endif /* LWIP_DEBUG */
902 sendstr(NEWLINE, com->conn);
903 return ESUCCESS;
904 }
905 }
906 #endif /* LWIP_IPV4 */
907
908 sendstr("Connection set up, connection identifier is ", com->conn);
909 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
910 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
911
912 return ESUCCESS;
913 }
914 /*-----------------------------------------------------------------------------------*/
915 static s8_t
com_usnd(struct command * com)916 com_usnd(struct command *com)
917 {
918 long i;
919 err_t err;
920 struct netbuf *buf;
921 char *mem;
922 u16_t len;
923 size_t tmp;
924
925 i = strtol(com->args[0], NULL, 10);
926
927 if (i > NCONNS) {
928 sendstr("Connection identifier too high."NEWLINE, com->conn);
929 return ESUCCESS;
930 }
931
932 if (conns[i] == NULL) {
933 sendstr("Connection identifier not in use."NEWLINE, com->conn);
934 return ESUCCESS;
935 }
936 tmp = strlen(com->args[1]) + 1;
937 if (tmp > 0xffff) {
938 sendstr("Invalid length."NEWLINE, com->conn);
939 return ESUCCESS;
940 }
941 len = (u16_t)tmp;
942
943 buf = netbuf_new();
944 mem = (char *)netbuf_alloc(buf, len);
945 if (mem == NULL) {
946 sendstr("Could not allocate memory for sending."NEWLINE, com->conn);
947 return ESUCCESS;
948 }
949 strncpy(mem, com->args[1], len);
950 err = netconn_send(conns[i], buf);
951 netbuf_delete(buf);
952 if (err != ERR_OK) {
953 sendstr("Could not send data: ", com->conn);
954 #ifdef LWIP_DEBUG
955 sendstr(lwip_strerr(err), com->conn);
956 #else
957 sendstr("(debugging must be turned on for error message to appear)", com->conn);
958 #endif /* LWIP_DEBUG */
959 sendstr(NEWLINE, com->conn);
960 return ESUCCESS;
961 }
962
963 sendstr("Data sent."NEWLINE, com->conn);
964 return ESUCCESS;
965 }
966 /*-----------------------------------------------------------------------------------*/
967 #if LWIP_SOCKET
968 /*-----------------------------------------------------------------------------------*/
969 static s8_t
com_idxtoname(struct command * com)970 com_idxtoname(struct command *com)
971 {
972 long i = strtol(com->args[0], NULL, 10);
973
974 if (lwip_if_indextoname((unsigned int)i, (char *)buffer)) {
975 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
976 sendstr(NEWLINE, com->conn);
977 } else {
978 snprintf((char *)buffer, sizeof(buffer), "if_indextoname() failed: %d"NEWLINE, errno);
979 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
980 }
981 return ESUCCESS;
982 }
983 /*-----------------------------------------------------------------------------------*/
984 static s8_t
com_nametoidx(struct command * com)985 com_nametoidx(struct command *com)
986 {
987 unsigned int idx = lwip_if_nametoindex(com->args[0]);
988
989 if (idx) {
990 snprintf((char *)buffer, sizeof(buffer), "%u"NEWLINE, idx);
991 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
992 } else {
993 sendstr("No interface found"NEWLINE, com->conn);
994 }
995 return ESUCCESS;
996 }
997 #endif /* LWIP_SOCKET */
998 /*-----------------------------------------------------------------------------------*/
999 #if LWIP_DNS
1000 static s8_t
com_gethostbyname(struct command * com)1001 com_gethostbyname(struct command *com)
1002 {
1003 ip_addr_t addr;
1004 err_t err = netconn_gethostbyname(com->args[0], &addr);
1005
1006 if (err == ERR_OK) {
1007 if (ipaddr_ntoa_r(&addr, (char *)buffer, sizeof(buffer))) {
1008 sendstr("Host found: ", com->conn);
1009 sendstr((char *)buffer, com->conn);
1010 sendstr(NEWLINE, com->conn);
1011 } else {
1012 sendstr("ipaddr_ntoa_r failed", com->conn);
1013 }
1014 } else {
1015 sendstr("No host found"NEWLINE, com->conn);
1016 }
1017 return ESUCCESS;
1018 }
1019 #endif /* LWIP_DNS */
1020 /*-----------------------------------------------------------------------------------*/
1021 static s8_t
com_help(struct command * com)1022 com_help(struct command *com)
1023 {
1024 sendstr(help_msg1, com->conn);
1025 sendstr(help_msg2, com->conn);
1026 sendstr(help_msg3, com->conn);
1027 return ESUCCESS;
1028 }
1029 /*-----------------------------------------------------------------------------------*/
1030 static s8_t
parse_command(struct command * com,u32_t len)1031 parse_command(struct command *com, u32_t len)
1032 {
1033 u16_t i;
1034 u16_t bufp;
1035
1036 if (strncmp((const char *)buffer, "open", 4) == 0) {
1037 com->exec = com_open;
1038 com->nargs = 2;
1039 } else if (strncmp((const char *)buffer, "lstn", 4) == 0) {
1040 com->exec = com_lstn;
1041 com->nargs = 1;
1042 } else if (strncmp((const char *)buffer, "acpt", 4) == 0) {
1043 com->exec = com_acpt;
1044 com->nargs = 1;
1045 } else if (strncmp((const char *)buffer, "clos", 4) == 0) {
1046 com->exec = com_clos;
1047 com->nargs = 1;
1048 #if LWIP_STATS
1049 } else if (strncmp((const char *)buffer, "stat", 4) == 0) {
1050 com->exec = com_stat;
1051 com->nargs = 0;
1052 #endif
1053 } else if (strncmp((const char *)buffer, "send", 4) == 0) {
1054 com->exec = com_send;
1055 com->nargs = 2;
1056 } else if (strncmp((const char *)buffer, "recv", 4) == 0) {
1057 com->exec = com_recv;
1058 com->nargs = 1;
1059 } else if (strncmp((const char *)buffer, "udpc", 4) == 0) {
1060 com->exec = com_udpc;
1061 com->nargs = 3;
1062 } else if (strncmp((const char *)buffer, "udpb", 4) == 0) {
1063 com->exec = com_udpb;
1064 com->nargs = 2;
1065 } else if (strncmp((const char *)buffer, "udpl", 4) == 0) {
1066 com->exec = com_udpl;
1067 com->nargs = 3;
1068 } else if (strncmp((const char *)buffer, "udpn", 4) == 0) {
1069 com->exec = com_udpn;
1070 com->nargs = 3;
1071 } else if (strncmp((const char *)buffer, "usnd", 4) == 0) {
1072 com->exec = com_usnd;
1073 com->nargs = 2;
1074 #if LWIP_SOCKET
1075 } else if (strncmp((const char *)buffer, "idxtoname", 9) == 0) {
1076 com->exec = com_idxtoname;
1077 com->nargs = 1;
1078 } else if (strncmp((const char *)buffer, "nametoidx", 9) == 0) {
1079 com->exec = com_nametoidx;
1080 com->nargs = 1;
1081 #endif /* LWIP_SOCKET */
1082 #if LWIP_DNS
1083 } else if (strncmp((const char *)buffer, "gethostnm", 9) == 0) {
1084 com->exec = com_gethostbyname;
1085 com->nargs = 1;
1086 #endif /* LWIP_DNS */
1087 } else if (strncmp((const char *)buffer, "help", 4) == 0) {
1088 com->exec = com_help;
1089 com->nargs = 0;
1090 } else if (strncmp((const char *)buffer, "quit", 4) == 0) {
1091 printf("quit"NEWLINE);
1092 return ECLOSED;
1093 } else {
1094 return ESYNTAX;
1095 }
1096
1097 if (com->nargs == 0) {
1098 return ESUCCESS;
1099 }
1100 bufp = 0;
1101 for(; bufp < len && buffer[bufp] != ' '; bufp++);
1102 for(i = 0; i < 10; i++) {
1103 for(; bufp < len && buffer[bufp] == ' '; bufp++);
1104 if (buffer[bufp] == '\r' ||
1105 buffer[bufp] == '\n') {
1106 buffer[bufp] = 0;
1107 if (i < com->nargs - 1) {
1108 return ETOOFEW;
1109 }
1110 if (i > com->nargs - 1) {
1111 return ETOOMANY;
1112 }
1113 break;
1114 }
1115 if (bufp > len) {
1116 return ETOOFEW;
1117 }
1118 com->args[i] = (char *)&buffer[bufp];
1119 for(; bufp < len && buffer[bufp] != ' ' && buffer[bufp] != '\r' &&
1120 buffer[bufp] != '\n'; bufp++) {
1121 if (buffer[bufp] == '\\') {
1122 buffer[bufp] = ' ';
1123 }
1124 }
1125 if (bufp > len) {
1126 return ESYNTAX;
1127 }
1128 buffer[bufp] = 0;
1129 bufp++;
1130 if (i == com->nargs - 1) {
1131 break;
1132 }
1133
1134 }
1135
1136 return ESUCCESS;
1137 }
1138 /*-----------------------------------------------------------------------------------*/
1139 static void
shell_error(s8_t err,struct netconn * conn)1140 shell_error(s8_t err, struct netconn *conn)
1141 {
1142 switch (err) {
1143 case ESYNTAX:
1144 sendstr("## Syntax error"NEWLINE, conn);
1145 break;
1146 case ETOOFEW:
1147 sendstr("## Too few arguments to command given"NEWLINE, conn);
1148 break;
1149 case ETOOMANY:
1150 sendstr("## Too many arguments to command given"NEWLINE, conn);
1151 break;
1152 case ECLOSED:
1153 sendstr("## Connection closed"NEWLINE, conn);
1154 break;
1155 default:
1156 /* unknown error, don't assert here */
1157 break;
1158 }
1159 }
1160 /*-----------------------------------------------------------------------------------*/
1161 static void
prompt(struct netconn * conn)1162 prompt(struct netconn *conn)
1163 {
1164 sendstr("> ", conn);
1165 }
1166 /*-----------------------------------------------------------------------------------*/
1167 static void
shell_main(struct netconn * conn)1168 shell_main(struct netconn *conn)
1169 {
1170 struct pbuf *p;
1171 u16_t len = 0, cur_len;
1172 struct command com;
1173 s8_t err;
1174 int i;
1175 err_t ret;
1176 #if SHELL_ECHO
1177 void *echomem;
1178 #endif /* SHELL_ECHO */
1179
1180 do {
1181 ret = netconn_recv_tcp_pbuf(conn, &p);
1182 if (ret == ERR_OK) {
1183 pbuf_copy_partial(p, &buffer[len], (u16_t)(BUFSIZE - len), 0);
1184 cur_len = p->tot_len;
1185 len = (u16_t)(len + cur_len);
1186 if ((len < cur_len) || (len > BUFSIZE)) {
1187 len = BUFSIZE;
1188 }
1189 #if SHELL_ECHO
1190 echomem = mem_malloc(cur_len);
1191 if (echomem != NULL) {
1192 pbuf_copy_partial(p, echomem, cur_len, 0);
1193 netconn_write(conn, echomem, cur_len, NETCONN_COPY);
1194 mem_free(echomem);
1195 }
1196 #endif /* SHELL_ECHO */
1197 pbuf_free(p);
1198 if (((len > 0) && ((buffer[len-1] == '\r') || (buffer[len-1] == '\n'))) ||
1199 (len >= BUFSIZE)) {
1200 if (buffer[0] != 0xff &&
1201 buffer[1] != 0xfe) {
1202 err = parse_command(&com, len);
1203 if (err == ESUCCESS) {
1204 com.conn = conn;
1205 err = com.exec(&com);
1206 }
1207 if (err == ECLOSED) {
1208 printf("Closed"NEWLINE);
1209 shell_error(err, conn);
1210 goto close;
1211 }
1212 if (err != ESUCCESS) {
1213 shell_error(err, conn);
1214 }
1215 } else {
1216 sendstr(NEWLINE NEWLINE
1217 "lwIP simple interactive shell."NEWLINE
1218 "(c) Copyright 2001, Swedish Institute of Computer Science."NEWLINE
1219 "Written by Adam Dunkels."NEWLINE
1220 "For help, try the \"help\" command."NEWLINE, conn);
1221 }
1222 if (ret == ERR_OK) {
1223 prompt(conn);
1224 }
1225 len = 0;
1226 }
1227 }
1228 } while (ret == ERR_OK);
1229 printf("err %s"NEWLINE, lwip_strerr(ret));
1230
1231 close:
1232 netconn_close(conn);
1233
1234 for(i = 0; i < NCONNS; i++) {
1235 if (conns[i] != NULL) {
1236 netconn_delete(conns[i]);
1237 }
1238 conns[i] = NULL;
1239 }
1240 }
1241 /*-----------------------------------------------------------------------------------*/
1242 static void
shell_thread(void * arg)1243 shell_thread(void *arg)
1244 {
1245 struct netconn *conn, *newconn;
1246 err_t err;
1247 LWIP_UNUSED_ARG(arg);
1248
1249 #if LWIP_IPV6
1250 conn = netconn_new(NETCONN_TCP_IPV6);
1251 LWIP_ERROR("shell: invalid conn", (conn != NULL), return;);
1252 err = netconn_bind(conn, IP6_ADDR_ANY, 23);
1253 #else /* LWIP_IPV6 */
1254 conn = netconn_new(NETCONN_TCP);
1255 LWIP_ERROR("shell: invalid conn", (conn != NULL), return;);
1256 err = netconn_bind(conn, IP_ADDR_ANY, 23);
1257 #endif /* LWIP_IPV6 */
1258 LWIP_ERROR("shell: netconn_bind failed", (err == ERR_OK), netconn_delete(conn); return;);
1259 err = netconn_listen(conn);
1260 LWIP_ERROR("shell: netconn_listen failed", (err == ERR_OK), netconn_delete(conn); return;);
1261
1262 while (1) {
1263 err = netconn_accept(conn, &newconn);
1264 if (err == ERR_OK) {
1265 shell_main(newconn);
1266 netconn_delete(newconn);
1267 }
1268 }
1269 }
1270 /*-----------------------------------------------------------------------------------*/
1271 void
shell_init(void)1272 shell_init(void)
1273 {
1274 sys_thread_new("shell_thread", shell_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
1275 }
1276
1277 #endif /* LWIP_NETCONN && LWIP_TCP */
1278