GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / ui / ui_tcpcmds.c
blobe092021a63bc9e714f5d16444469ec38bcd8d302
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * TCP protocol commands File: ui_tcpcmds.c
5 *
6 * This file contains commands that make use of the TCP protocol
7 * in CFE, assuming it's configured.
8 *
9 * Author: Mitch Lichtenberg (mpl@broadcom.com)
11 *********************************************************************
13 * Copyright 2000,2001,2002,2003
14 * Broadcom Corporation. All rights reserved.
16 * This software is furnished under license and may be used and
17 * copied only in accordance with the following terms and
18 * conditions. Subject to these conditions, you may download,
19 * copy, install, use, modify and distribute modified or unmodified
20 * copies of this software in source and/or binary form. No title
21 * or ownership is transferred hereby.
23 * 1) Any source code used, modified or distributed must reproduce
24 * and retain this copyright notice and list of conditions
25 * as they appear in the source file.
27 * 2) No right is granted to use any trade name, trademark, or
28 * logo of Broadcom Corporation. The "Broadcom Corporation"
29 * name may not be used to endorse or promote products derived
30 * from this software without the prior written permission of
31 * Broadcom Corporation.
33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGE.
46 ********************************************************************* */
49 #include "lib_types.h"
50 #include "lib_string.h"
51 #include "lib_queue.h"
52 #include "lib_malloc.h"
53 #include "lib_printf.h"
55 #include "cfe_timer.h"
57 #include "cfe_error.h"
58 #include "cfe_console.h"
60 #include "ui_command.h"
61 #include "cfe.h"
63 #include "cfe_iocb.h"
64 #include "cfe_devfuncs.h"
66 #include "bsp_config.h"
68 #if CFG_TCP
69 #include "net_ebuf.h"
70 #include "net_api.h"
71 #endif
74 /* *********************************************************************
75 * Configuration
76 ********************************************************************* */
78 /* *********************************************************************
79 * prototypes
80 ********************************************************************* */
82 #if CFG_TCP
84 int ui_init_tcpcmds(void);
86 static int ui_cmd_rlogin(ui_cmdline_t *cmd,int argc,char *argv[]);
87 static int ui_cmd_connect(ui_cmdline_t *cmd,int argc,char *argv[]);
88 static int ui_cmd_listen(ui_cmdline_t *cmd,int argc,char *argv[]);
89 static int ui_cmd_tcpconstest(ui_cmdline_t *cmd,int argc,char *argv[]);
90 static int ui_cmd_ttcp(ui_cmdline_t *cmd,int argc,char *argv[]);
91 #define isdigit(d) (((d) >= '0') && ((d) <= '9'))
94 /* *********************************************************************
95 * ui_init_tcpcmds()
97 * Add TCP-specific commands to the command table
99 * Input parameters:
100 * nothing
102 * Return value:
104 ********************************************************************* */
107 int ui_init_tcpcmds(void)
110 cmd_addcmd("rlogin",
111 ui_cmd_rlogin,
112 NULL,
113 "mini rlogin client.",
114 "rlogin hostname [username]\n\n"
115 "Connects to a remote system using the RLOGIN protocol. The remote"
116 "system must have appropriate permissions in place (usually via the"
117 "file '.rhosts') for CFE to connect. To terminate the session, type"
118 "a tilde (~) character followed by a period (.)",
119 "");
121 cmd_addcmd("tcp connect",
122 ui_cmd_connect,
123 NULL,
124 "TCP connection test.",
125 "tcp connect hostname [portnum]",
126 "-q;sink output, don't display on terminal|"
127 "-d;Send junk data to discard|"
128 "-nodelay;set nodelay option on socket|"
129 "-srcport=*;Specify the source port");
131 cmd_addcmd("tcp listen",
132 ui_cmd_listen,
133 NULL,
134 "port listener.",
135 "tcp listen portnum",
136 "-q;sink output, don't display on terminal|"
137 "-d;Send junk data to discard|"
138 "-nodelay;set nodelay option on socket");
141 cmd_addcmd("tcp constest",
142 ui_cmd_tcpconstest,
143 NULL,
144 "tcp console test.",
145 "tcp constest device",
146 "");
148 cmd_addcmd("ttcp",
149 ui_cmd_ttcp,
150 NULL,
151 "TCP test command.",
152 "ttcp -t [-options] host\n"
153 "ttcp -r [-options]\n\n",
154 "-t;Source a pattern to the network|"
155 "-r;Sink (discard) data from the network|"
156 "-D;Don't buffer TCP writes (TCP_NODELAY)|"
157 "-n=*;Number of buffers to send (-t only) (default 2048)|"
158 "-l=*;Size of buffer to send/receive (default 2048)|"
159 "-p=*;Port number to use (default 5001)");
161 return 0;
168 static unsigned long rand(void)
170 static unsigned long seed = 1;
171 long x, hi, lo, t;
173 x = seed;
174 hi = x / 127773;
175 lo = x % 127773;
176 t = 16807 * lo - 2836 * hi;
177 if (t <= 0) t += 0x7fffffff;
178 seed = t;
179 return t;
183 static int ui_cmd_rlogin(ui_cmdline_t *cmd,int argc,char *argv[])
185 int s;
186 uint8_t hostaddr[IP_ADDR_LEN];
187 char *host;
188 int res;
189 int connflag;
190 int rxdata;
191 int sport;
192 uint8_t data[100];
193 int tilde;
194 char *username;
195 uint8_t *p;
198 * Process args
201 host = cmd_getarg(cmd,0);
202 if (!host) return ui_showusage(cmd);
204 username = cmd_getarg(cmd,1);
205 if (!username) username = "";
208 * Look up remote host
211 if (isdigit(*host)) {
212 if (parseipaddr(host,hostaddr) < 0) {
213 xprintf("Invalid IP address: %s\n",host);
214 return -1;
217 else {
218 res = dns_lookup(host,hostaddr);
219 if (res < 0) {
220 return ui_showerror(res,"Could not resolve IP address of host %s",host);
225 * Create TCP socket and bind to a port number less than 1023
226 * See RFC1282 for more info about this
229 s = tcp_socket();
231 if (s < 0) {
232 return ui_showerror(s,"Could not create TCP socket");
235 res = 0;
236 tilde = 0;
237 for (sport = 1023; sport > 513; sport--) {
238 res = tcp_bind(s,sport);
239 if (res == 0) break;
242 if (sport == 513) {
243 ui_showerror(res,"No ports available for RLOGIN");
244 return res;
248 * Establish a connection. Our sockets default to nonblocking
249 * so we want to switch to blocking temporarily to
250 * let the tcp_connect routine do this by itself.
253 tcp_setflags(s,0);
254 res = tcp_connect(s,hostaddr,513);
255 if (res < 0) {
256 ui_showerror(res,"Could not connect to host %I",hostaddr);
257 tcp_close(s);
258 return res;
263 * Construct the initial RLOGIN sequence to include
264 * our user name and terminal type
267 p = data;
268 *p++ = '\0';
269 p += sprintf(p,"%s",username) + 1;
270 p += sprintf(p,"%s",username) + 1;
271 p += sprintf(p,"vt100/38400") + 1;
273 tcp_send(s,data,p-&data[0]);
275 res = tcp_recv(s,data,1); /* receive result code */
276 if (res <= 0) {
277 goto remdisc;
281 * Switch back to nonblocking I/O for the loop
284 tcp_setflags(s,TCPFLG_NBIO);
287 * Begin processing loop
290 connflag = TRUE;
291 for (;;) {
294 * Test connection status
297 tcp_status(s,&connflag,&rxdata,NULL);
298 if (connflag != TCPSTATUS_CONNECTED) {
299 goto remdisc;
303 * Process received data
306 if (rxdata != 0) {
307 res = tcp_recv(s,data,sizeof(data));
308 if (res > 0) {
309 console_write(data,res);
311 if (res < 0) {
312 ui_showerror(res,"TCP read error");
313 break;
318 * Process transmitted data
321 if (console_status()) {
322 console_read(data,1);
323 if (tilde == 1) {
324 if (data[0] == '.') break;
325 tcp_send(s,data,1);
327 else {
328 if (data[0] == '~') tilde = 1;
329 else tcp_send(s,data,1);
334 * Give the background a chance
337 POLL();
340 printf("Disconnecting...");
341 tcp_close(s);
342 printf("done.\n");
343 return 0;
345 remdisc:
346 printf("Remote host is no longer connected.\n");
347 tcp_close(s);
348 return 0;
353 static int ui_cmd_connect(ui_cmdline_t *cmd,int argc,char *argv[])
355 int s;
356 uint8_t hostaddr[IP_ADDR_LEN];
357 char *host;
358 char *port;
359 int res;
360 int connflag;
361 int rxdata;
362 uint8_t data[100];
363 int quiet;
364 int discard;
365 int total = 0;
366 int total2 = 0;
367 char b = 0;
368 cfe_timer_t t;
369 char *bigbuf;
370 int nodelay;
371 char *sport = NULL;
373 bigbuf = KMALLOC(4096,0);
374 for (res = 0; res < 4096; res++) bigbuf[res] = 'A'+(res%26);
376 quiet = cmd_sw_isset(cmd,"-q");
377 discard = cmd_sw_isset(cmd,"-d");
378 nodelay = cmd_sw_isset(cmd,"-nodelay");
380 host = cmd_getarg(cmd,0);
381 if (!host) return -1;
383 port = cmd_getarg(cmd,1);
384 if (!port) port = "23";
386 if (strcmp(port,"discard") == 0) port = "9";
387 else if (strcmp(port,"chargen") == 0) port = "19";
388 else if (strcmp(port,"echo") == 0) port = "7";
390 if (isdigit(*host)) {
391 if (parseipaddr(host,hostaddr) < 0) {
392 xprintf("Invalid IP address: %s\n",host);
393 return -1;
396 else {
397 res = dns_lookup(host,hostaddr);
398 if (res < 0) {
399 return ui_showerror(res,"Could not resolve IP address of host %s",host);
404 s = tcp_socket();
406 if (s < 0) {
407 return ui_showerror(s,"Could not create TCP socket");
410 if (cmd_sw_value(cmd,"-srcport",&sport)) {
411 res = tcp_bind(s,atoi(sport));
412 if (res < 0) {
413 ui_showerror(res,"Could not bind to port %s",sport);
414 tcp_close(s);
415 return res;
419 res = tcp_connect(s,hostaddr,atoi(port));
420 if (res < 0) {
421 ui_showerror(res,"Could not connect to host %I",hostaddr);
422 tcp_close(s);
423 return res;
426 TIMER_SET(t,CFE_HZ*30);
427 connflag = 0;
428 while (!TIMER_EXPIRED(t)) {
429 POLL();
430 tcp_status(s,&connflag,NULL,NULL);
431 if (connflag == TCPSTATUS_CONNECTING) continue;
432 break;
435 if (connflag != TCPSTATUS_CONNECTED) {
436 printf("Could not connect to remote host\n");
437 tcp_close(s);
438 return -1;
440 else {
441 printf("Connected to remote host.\n");
445 if (nodelay) tcp_setflags(s,TCPFLG_NODELAY);
447 connflag = TRUE;
448 for (;;) {
449 tcp_status(s,&connflag,&rxdata,NULL);
450 if (connflag != TCPSTATUS_CONNECTED) {
451 printf("Remote host is no longer connected.\n");
452 break;
454 if (rxdata != 0) {
455 res = tcp_recv(s,data,sizeof(data));
456 if (res > 0) {
457 if (quiet) {
458 total += res;
459 if (total > 1000000) {
460 total -= 1000000;
461 printf(".");
464 else {
465 console_write(data,res);
468 if (res < 0) {
469 ui_showerror(res,"TCP read error");
472 if (console_status()) {
473 console_read(data,1);
474 if (data[0] == 1) break;
475 else if (data[0] == 3) break;
476 else if (data[0] == 4) {
477 for (res = 0; res < 100; res++) data[res] = 'A'+(res%26);
478 tcp_send(s,data,100);
480 else if (data[0] == 5) tcp_send(s,bigbuf,2048);
481 else if (data[0] == 2) tcp_debug(s,0);
482 else tcp_send(s,data,1);
484 if (discard) {
485 res = rand() % sizeof(data);
486 memset(data,b,res);
487 b++;
488 res = tcp_send(s,data,res);
489 if (res > 0) {
490 total2 += res;
491 if (total2 > 1000000) {
492 total2 -= 1000000;
493 printf("+");
499 POLL();
502 printf("Disconnecting...");
503 tcp_close(s);
504 printf("done.\n");
506 KFREE(bigbuf);
508 return 0;
512 static int ui_cmd_listen(ui_cmdline_t *cmd,int argc,char *argv[])
514 int s;
515 char *port;
516 int res;
517 int connflag;
518 int rxdata;
519 uint8_t data[100];
520 int quiet;
521 int discard;
522 int total = 0;
523 int total2 = 0;
524 char b = 0;
525 char *bigbuf;
526 uint16_t p;
527 uint16_t remport;
528 uint8_t remaddr[IP_ADDR_LEN];
529 int nodelay;
531 bigbuf = KMALLOC(4096,0);
532 for (res = 0; res < 4096; res++) bigbuf[res] = 'A'+(res%26);
534 quiet = cmd_sw_isset(cmd,"-q");
535 discard = cmd_sw_isset(cmd,"-d");
536 nodelay = cmd_sw_isset(cmd,"-nodelay");
538 port = cmd_getarg(cmd,0);
539 if (!port) port = "1234";
540 p = atoi(port);
542 s = tcp_socket();
544 if (s < 0) {
545 return ui_showerror(s,"Could not create TCP socket");
548 res = tcp_listen(s,p);
549 if (res < 0) {
550 ui_showerror(res,"Could not set socket to listen");
551 tcp_close(s);
552 return res;
555 printf("Listening...");
556 connflag = FALSE;
557 for (;;) {
558 if (console_status()) break;
559 tcp_status(s,&connflag,NULL,NULL);
560 if (connflag == TCPSTATUS_CONNECTED) break;
561 POLL();
564 if (connflag != TCPSTATUS_CONNECTED) {
565 printf("No connection received from remote host\n");
566 tcp_close(s);
567 return -1;
570 tcp_peeraddr(s,remaddr,&remport);
571 printf("Connection from port %u on %I\n",remport,remaddr);
573 if (nodelay) tcp_setflags(s,TCPFLG_NODELAY);
575 connflag = TRUE;
576 for (;;) {
577 tcp_status(s,&connflag,&rxdata,NULL);
578 if (connflag != TCPSTATUS_CONNECTED) {
579 printf("Remote host is no longer connected.\n");
580 break;
582 if (rxdata != 0) {
583 res = tcp_recv(s,data,sizeof(data));
584 if (res > 0) {
585 if (quiet) {
586 total += res;
587 if (total > 1000000) {
588 total -= 1000000;
589 printf(".");
592 else {
593 console_write(data,res);
596 if (res < 0) {
597 ui_showerror(res,"TCP read error");
600 if (console_status()) {
601 console_read(data,1);
602 if (data[0] == 1) break;
603 if (data[0] == 3) break;
604 if (data[0] == 4) {
605 for (res = 0; res < 100; res++) data[res] = 'A'+(res%26);
606 tcp_send(s,data,100);
608 if (data[0] == 5) tcp_send(s,bigbuf,2048);
609 if (data[0] == 2) tcp_debug(s,0);
610 else tcp_send(s,data,1);
612 if (discard) {
613 res = rand() % sizeof(data);
614 memset(data,b,res);
615 b++;
616 res = tcp_send(s,data,res);
617 if (res > 0) {
618 total2 += res;
619 if (total2 > 1000000) {
620 total2 -= 1000000;
621 printf("+");
627 POLL();
631 printf("Disconnecting...");
632 tcp_close(s);
633 printf("done.\n");
635 KFREE(bigbuf);
637 return 0;
641 static int ui_cmd_tcpconstest(ui_cmdline_t *cmd,int argc,char *argv[])
643 char *x;
644 int fh;
645 int res;
646 uint8_t data[100];
648 x = cmd_getarg(cmd,0);
649 if (!x) return ui_showusage(cmd);
651 fh = cfe_open(x);
652 if (fh < 0) return ui_showerror(fh,"Could not open device %s",x);
654 for (;;) {
655 if (console_status()) break;
656 res = cfe_read(fh,data,sizeof(data));
657 if (res < 0) {
658 ui_showerror(res,"could not read data");
659 break;
661 console_write(data,res);
664 cfe_close(fh);
666 return 0;
669 static int ui_cmd_ttcp(ui_cmdline_t *cmd,int argc,char *argv[])
671 int s;
672 uint8_t hostaddr[IP_ADDR_LEN];
673 char *host;
674 int res;
675 int totalbytes = 0;
676 int totalbufs = 0;
677 cfe_timer_t start_time;
678 cfe_timer_t stop_time;
679 cfe_timer_t t;
680 int connflag;
681 char *bigbuf;
682 int nodelay;
683 int numbuf;
684 int buflen;
685 int txmode,rxmode;
686 uint16_t port;
688 char *x;
690 if (cmd_sw_value(cmd,"-n",&x)) numbuf = atoi(x);
691 else numbuf = 2048;
693 if (cmd_sw_value(cmd,"-l",&x)) buflen = atoi(x);
694 else buflen = 2048;
696 if (cmd_sw_value(cmd,"-p",&x)) port = atoi(x);
697 else port = 5001;
699 if ((numbuf == 0) || (buflen == 0)) return ui_showusage(cmd);
702 bigbuf = KMALLOC(buflen,0);
703 for (res = 0; res < buflen; res++) bigbuf[res] = 'A'+(res%26);
705 txmode = cmd_sw_isset(cmd,"-t");
706 rxmode = cmd_sw_isset(cmd,"-r");
708 if (!(txmode ^ rxmode)) {
709 return ui_showerror(-1,"You must specify one of -t or -r");
712 nodelay = cmd_sw_isset(cmd,"-D");
714 if (txmode) {
715 host = cmd_getarg(cmd,0);
716 if (!host) return ui_showusage(cmd);
718 if (isdigit(*host)) {
719 if (parseipaddr(host,hostaddr) < 0) {
720 return ui_showerror(-1,"Invalid IP address: %s\n",host);
723 else {
724 res = dns_lookup(host,hostaddr);
725 if (res < 0) {
726 return ui_showerror(res,"Could not resolve IP address of host %s",host);
732 s = tcp_socket();
734 if (s < 0) {
735 return ui_showerror(s,"Could not create TCP socket");
739 if (txmode) {
740 res = tcp_connect(s,hostaddr,port);
741 if (res < 0) {
742 ui_showerror(res,"Could not connect to host %I",hostaddr);
743 tcp_close(s);
744 return res;
747 TIMER_SET(t,CFE_HZ*30);
748 connflag = 0;
749 while (!TIMER_EXPIRED(t)) {
750 POLL();
751 tcp_status(s,&connflag,NULL,NULL);
752 if (connflag == TCPSTATUS_CONNECTING) continue;
753 break;
756 if (connflag != TCPSTATUS_CONNECTED) {
757 printf("Could not connect to remote host\n");
758 tcp_close(s);
759 return -1;
761 else {
762 printf("Connected to remote host.\n");
766 if (rxmode) {
767 printf("Waiting for connection on port %d: ",port);
768 tcp_listen(s,port);
769 for (;;) {
770 if (console_status()) break;
771 tcp_status(s,&connflag,NULL,NULL);
772 if (connflag == TCPSTATUS_CONNECTED) break;
773 POLL();
775 if (connflag != TCPSTATUS_CONNECTED) {
776 printf("No connection received from remote host\n");
777 tcp_close(s);
778 return -1;
780 printf("done.\n");
784 if (nodelay) tcp_setflags(s,TCPFLG_NODELAY); /* also sets blocking */
785 else tcp_setflags(s,0);
787 start_time = cfe_ticks;
789 if (rxmode) {
790 while (1) {
791 POLL();
792 res = tcp_recv(s,bigbuf,buflen);
793 if (res != buflen) break;
794 totalbytes += res;
795 totalbufs++;
798 else {
799 while (numbuf > 0) {
800 POLL();
801 res = tcp_send(s,bigbuf,buflen);
802 if (res != buflen) break;
803 numbuf--;
804 totalbytes += res;
805 totalbufs++;
809 stop_time = cfe_ticks;
811 tcp_close(s);
813 if ((res < 0) && !rxmode) {
814 ui_showerror(res,"Network I/O error");
816 else {
817 printf("%d bytes transferred via %d calls in %lld ticks\n",
818 totalbytes,totalbufs,stop_time-start_time);
822 KFREE(bigbuf);
824 return 0;
828 #endif /* CFG_TCP */