From 6cc63cbe657c3ee664727cce1a54acc7e7b5fe9d Mon Sep 17 00:00:00 2001 From: Stephen Clark Date: Wed, 2 Jun 2021 09:59:51 -0500 Subject: rtemsbsd: Made TTCP command build for RTEMS Updated ttcp.c to build clean for RTEMS 6 and the machines it originally built for. Also fixed ttcp.c to close network sockets after completion. Defined a shell command for TTCP in rtems-bsd-shell-ttcp.c. Added TTCP to the list of RTEMS network commands in netcmds-config.h. Added declaration of the TTCP shell command to rtems-bsd-commands.h. Modified libbsd.py to make waf build TTCP and its shell command. --- libbsd.py | 2 + rtemsbsd/include/machine/rtems-bsd-commands.h | 2 + rtemsbsd/include/rtems/netcmds-config.h | 2 + rtemsbsd/rtems/rtems-bsd-shell-ttcp.c | 39 ++++ rtemsbsd/ttcp/README | 11 +- rtemsbsd/ttcp/ttcp.c | 275 +++++++++++++++++++++----- 6 files changed, 270 insertions(+), 61 deletions(-) create mode 100644 rtemsbsd/rtems/rtems-bsd-shell-ttcp.c diff --git a/libbsd.py b/libbsd.py index c6a88fa1..426e2d2e 100644 --- a/libbsd.py +++ b/libbsd.py @@ -272,6 +272,7 @@ class rtems(builder.Module): 'rtems/rtems-bsd-shell-tcpdump.c', 'rtems/rtems-bsd-shell-vmstat.c', 'rtems/rtems-bsd-shell-wlanstats.c', + 'rtems/rtems-bsd-shell-ttcp.c', 'rtems/rtems-kvm.c', 'rtems/rtems-program.c', 'rtems/rtems-program-socket.c', @@ -295,6 +296,7 @@ class rtems(builder.Module): 'pppd/upap.c', 'pppd/utils.c', 'telnetd/telnetd-service.c', + 'ttcp/ttcp.c', ], mm.generator['source']() ) diff --git a/rtemsbsd/include/machine/rtems-bsd-commands.h b/rtemsbsd/include/machine/rtems-bsd-commands.h index d314471f..d82c274c 100644 --- a/rtemsbsd/include/machine/rtems-bsd-commands.h +++ b/rtemsbsd/include/machine/rtems-bsd-commands.h @@ -84,6 +84,8 @@ int rtems_bsd_command_setkey(int argc, char **argv); int rtems_bsd_command_openssl(int argc, char **argv); +int rtems_shell_main_ttcp(int argc, char **argv); + __END_DECLS #endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_COMMANDS_H_ */ diff --git a/rtemsbsd/include/rtems/netcmds-config.h b/rtemsbsd/include/rtems/netcmds-config.h index bc493af4..c1d56eb3 100644 --- a/rtemsbsd/include/rtems/netcmds-config.h +++ b/rtemsbsd/include/rtems/netcmds-config.h @@ -29,6 +29,8 @@ extern rtems_shell_cmd_t rtems_shell_PFCTL_Command; extern rtems_shell_cmd_t rtems_shell_PING_Command; extern rtems_shell_cmd_t rtems_shell_PING6_Command; +extern rtems_shell_cmd_t rtems_shell_TTCP_Command; + extern rtems_shell_cmd_t rtems_shell_IFCONFIG_Command; extern rtems_shell_cmd_t rtems_shell_IFMCSTAT_Command; diff --git a/rtemsbsd/rtems/rtems-bsd-shell-ttcp.c b/rtemsbsd/rtems/rtems-bsd-shell-ttcp.c new file mode 100644 index 00000000..babaa011 --- /dev/null +++ b/rtemsbsd/rtems/rtems-bsd-shell-ttcp.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * COPYRIGHT (c) 2021. On-Line Applications Research Corporation (OAR). + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +#include + +rtems_shell_cmd_t rtems_shell_TTCP_Command = { + "ttcp", /* name */ + "ttcp -h # to get help", /* usage */ + "net", /* topic */ + rtems_shell_main_ttcp, /* command */ + NULL, /* alias */ + NULL /* next */ +}; diff --git a/rtemsbsd/ttcp/README b/rtemsbsd/ttcp/README index 3caf2e22..35db3892 100644 --- a/rtemsbsd/ttcp/README +++ b/rtemsbsd/ttcp/README @@ -7,14 +7,9 @@ but please do leave the credit notices in the source and man page intact. Contents of this directory: -ttcp.c Source that runs on IRIX 3.3.x and 4.0.x systems - and BSD-based systems. This version also uses getopt(3) - and has 2 new options: -f and -T. - -ttcp.c-brl Original source from BRL. - -ttcp.1 Manual page (describes ttcp.c options, which are a - superset of the other version). +ttcp.c Source that runs on IRIX 3.3.x and 4.0.x systems, + BSD-based systems, and RTEMS. This version also + uses getopt(3) and has 2 new options: -f and -T. How to get TCP performance numbers: diff --git a/rtemsbsd/ttcp/ttcp.c b/rtemsbsd/ttcp/ttcp.c index 07b05ab1..d361fece 100644 --- a/rtemsbsd/ttcp/ttcp.c +++ b/rtemsbsd/ttcp/ttcp.c @@ -45,6 +45,7 @@ /* #define BSD41a */ /* #define SYSV */ /* required on SGI IRIX releases before 3.3 */ +//The millisecond delay should work on a modern OS but can be disabled if not #define ENABLE_NANOSLEEP_DELAY #include @@ -60,6 +61,10 @@ #include #include /* struct timeval */ +#if defined(ENABLE_NANOSLEEP_DELAY) +#include +#endif + #include #include @@ -74,48 +79,95 @@ struct rusage { #include #endif -struct sockaddr_in sinme; -struct sockaddr_in sinhim; -struct sockaddr_in frominet; +#if defined(__rtems__) +#define __need_getopt_newlib +#include +#include +#endif + +static struct sockaddr_in sinme; +static struct sockaddr_in sinhim; +static struct sockaddr_in frominet; /* these make it easier to avoid warnings */ -struct sockaddr *sinhim_p = (struct sockaddr *) &sinhim; -struct sockaddr *sinme_p = (struct sockaddr *) &sinme; -struct sockaddr *frominet_p = (struct sockaddr *) &frominet; - -int domain; -socklen_t fromlen; -int fd; /* fd of network socket */ - -int buflen = 8 * 1024; /* length of buffer */ -char *buf; /* ptr to dynamic buffer */ -int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ - -int bufoffset = 0; /* align buffer to this */ -int bufalign = 16*1024; /* modulo this */ - -int udp = 0; /* 0 = tcp, !0 = udp */ -int options = 0; /* socket options */ -int one = 1; /* for 4.3 BSD style setsockopt() */ -short port = 5001; /* TCP port number */ -char *host; /* ptr to name of host */ -int trans; /* 0=receive, !0=transmit mode */ -int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ -int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc +static struct sockaddr *sinhim_p = (struct sockaddr *) &sinhim; +static struct sockaddr *sinme_p = (struct sockaddr *) &sinme; +static struct sockaddr *frominet_p = (struct sockaddr *) &frominet; + +static int domain; +static socklen_t fromlen; +static int fd; /* fd of network socket */ + +static int buflen = 8 * 1024; /* length of buffer */ +static char *buf; /* ptr to dynamic buffer */ +static char *alloc_buf; /* ptr to beginning of memory allocated for buf */ +static int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +static int bufoffset = 0; /* align buffer to this */ +static int bufalign = 16*1024; /* modulo this */ + +static int udp = 0; /* 0 = tcp, !0 = udp */ +static int options = 0; /* socket options */ +static int one = 1; /* for 4.3 BSD style setsockopt() */ +static short port = 5001; /* TCP port number */ +static char *host; /* ptr to name of host */ +static int trans; /* 0=receive, !0=transmit mode */ +static int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +static int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc * resource usage. */ -int nodelay = 0; /* set TCP_NODELAY socket option */ -int b_flag = 0; /* use mread() */ -int sockbufsize = 0; /* socket buffer size to use */ -char fmt = 'K'; /* output format: k = kilobits, K = kilobytes, +static int nodelay = 0; /* set TCP_NODELAY socket option */ +static int b_flag = 0; /* use mread() */ +static int sockbufsize = 0; /* socket buffer size to use */ +static char fmt = 'K'; /* output format: k = kilobits, K = kilobytes, * m = megabits, M = megabytes, * g = gigabits, G = gigabytes */ -int touchdata = 0; /* access data after reading */ -long milliseconds = 0; /* delay in milliseconds */ +static int touchdata = 0; /* access data after reading */ +static long milliseconds = 0; /* delay in milliseconds */ -struct hostent *addr; -extern int errno; -extern int optind; -extern char *optarg; +static struct hostent *addr; +static void initialize_vars(void) +{ + memset(&sinme, 0, sizeof(sinme)); + memset(&sinhim, 0, sizeof(sinhim)); + memset(&frominet, 0, sizeof(frominet)); + + /* these make it easier to avoid warnings */ + sinhim_p = (struct sockaddr *) &sinhim; + sinme_p = (struct sockaddr *) &sinme; + frominet_p = (struct sockaddr *) &frominet; + + domain = 0; + fromlen = 0; + fd = 0; /* fd of network socket */ + + buflen = 8 * 1024; /* length of buffer */ + buf = NULL; /* ptr to dynamic buffer */ + alloc_buf = NULL; /* ptr to beginning of memory allocated for buf */ + nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + + bufoffset = 0; /* align buffer to this */ + bufalign = 16*1024; /* modulo this */ + + udp = 0; /* 0 = tcp, !0 = udp */ + options = 0; /* socket options */ + one = 1; /* for 4.3 BSD style setsockopt() */ + port = 5001; /* TCP port number */ + host = NULL; /* ptr to name of host */ + trans = 0; /* 0=receive, !0=transmit mode */ + sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ + verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ + nodelay = 0; /* set TCP_NODELAY socket option */ + b_flag = 0; /* use mread() */ + sockbufsize = 0; /* socket buffer size to use */ + fmt = 'K'; /* output format: k = kilobits, K = kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ + touchdata = 0; /* access data after reading */ + milliseconds = 0; /* delay in milliseconds */ + + addr = NULL; +} char Usage[] = "\ Usage: ttcp -t [-options] host [ < in ]\n\ @@ -173,16 +225,34 @@ void millisleep(long msec) nanosleep( &req, NULL ); #endif } + +#if (defined (__rtems__)) +int rtems_shell_main_ttcp(argc,argv) +#else int main(argc,argv) +#endif int argc; char **argv; { + initialize_vars(); unsigned long addr_tmp; int c; if (argc < 2) goto usage; +#ifdef __rtems__ + struct getopt_data getopt_reent; +#define optarg getopt_reent.optarg +#define optind getopt_reent.optind +#define opterr getopt.reent.opterr +#define optopt getopt.reent.optopt + memset(&getopt_reent, 0, sizeof(getopt_data)); + while ((c = getopt_r(argc, argv, + "drstuvBDTb:f:l:m:n:p:A:O:", + &getopt_reent)) != -1) { +#else while ((c = getopt(argc, argv, "drstuvBDTb:f:l:m:n:p:A:O:")) != -1) { +#endif switch (c) { case 'B': @@ -270,8 +340,12 @@ char **argv; sinhim.sin_addr.s_addr = inet_addr(host); #endif } else { - if ((addr=gethostbyname(host)) == NULL) + if ((addr=gethostbyname(host)) == NULL) { err("bad hostname"); +#ifdef __rtems__ + return 1; +#endif + } sinhim.sin_family = addr->h_addrtype; bcopy(addr->h_addr,(char*)&addr_tmp, addr->h_length); #if defined(cray) @@ -292,10 +366,15 @@ char **argv; buflen = 5; /* send more than the sentinel size */ } - if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL) + if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL) { err("malloc"); +#ifdef __rtems__ + return 1; +#endif + } + alloc_buf = buf; if (bufalign != 0) - buf +=(bufalign - ((int)buf % bufalign) + bufoffset) % bufalign; + buf +=(bufalign - ((intptr_t)buf % bufalign) + bufoffset) % bufalign; if (trans) { fprintf(stdout, @@ -313,24 +392,40 @@ char **argv; fprintf(stdout, " %s\n", udp?"udp":"tcp"); } - if ((fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0)) < 0) + if ((fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0)) < 0) { err("socket"); +#ifdef __rtems__ + return 1; +#endif + } mes("socket"); - if (bind(fd, sinme_p, sizeof(sinme)) < 0) + if (bind(fd, sinme_p, sizeof(sinme)) < 0) { err("bind"); +#ifdef __rtems__ + return 1; +#endif + } #if defined(SO_SNDBUF) || defined(SO_RCVBUF) if (sockbufsize) { if (trans) { if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, - sizeof sockbufsize) < 0) + sizeof sockbufsize) < 0) { err("setsockopt: sndbuf"); +#ifdef __rtems__ + return 1; +#endif + } mes("sndbuf"); } else { if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, - sizeof sockbufsize) < 0) + sizeof sockbufsize) < 0) { err("setsockopt: rcvbuf"); +#ifdef __rtems__ + return 1; +#endif + } mes("rcvbuf"); } } @@ -344,24 +439,36 @@ char **argv; /* We are the client if transmitting */ if (options) { #if defined(BSD42) - if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) { #else /* BSD43 */ - if( setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one)) < 0) + if( setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one)) < 0) { #endif err("setsockopt"); +#ifdef __rtems__ + return 1; +#endif + } } #ifdef TCP_NODELAY if (nodelay) { struct protoent *p; p = getprotobyname("tcp"); if( p && setsockopt(fd, p->p_proto, TCP_NODELAY, - &one, sizeof(one)) < 0) + &one, sizeof(one)) < 0) { err("setsockopt: nodelay"); +#ifdef __rtems__ + return 1; +#endif + } mes("nodelay"); } #endif - if(connect(fd, sinhim_p, sizeof(sinhim) ) < 0) + if(connect(fd, sinhim_p, sizeof(sinhim) ) < 0) { err("connect"); +#ifdef __rtems__ + return 1; +#endif + } mes("connect"); } else { /* otherwise, we are the server and @@ -374,21 +481,41 @@ char **argv; #endif if(options) { #if defined(BSD42) - if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) { #else /* BSD43 */ - if( setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one)) < 0) + if( setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one)) < 0) { #endif err("setsockopt"); +#ifdef __rtems__ + return 1; +#endif + } } fromlen = sizeof(frominet); domain = AF_INET; - if((fd=accept(fd, frominet_p, &fromlen) ) < 0) + int fd_list = fd; + if((fd=accept(fd_list, frominet_p, &fromlen) ) < 0) { err("accept"); +#ifdef __rtems__ + return 1; +#endif + } + + if(close(fd_list) < 0) { + err("close"); +#ifdef __rtems__ + return 1; +#endif + } + { struct sockaddr_in peer; socklen_t peerlen = sizeof(peer); if (getpeername(fd, (struct sockaddr *) &peer, &peerlen) < 0) { err("getpeername"); +#ifdef __rtems__ + return 1; +#endif } fprintf(stderr,"ttcp-r: accept from %s\n", inet_ntoa(peer.sin_addr)); @@ -438,7 +565,12 @@ char **argv; nbytes += cnt; } } - if(errno) err("IO"); + if(errno) { + err("IO"); +#ifdef __rtems__ + return 1; +#endif + } (void)read_timer(stats,sizeof(stats)); if(udp&&trans) { (void)Nwrite( fd, buf, 4 ); /* rcvr end */ @@ -446,6 +578,14 @@ char **argv; (void)Nwrite( fd, buf, 4 ); /* rcvr end */ (void)Nwrite( fd, buf, 4 ); /* rcvr end */ } + + if(close(fd) < 0) { + err("close"); +#ifdef __rtems__ + return 1; +#endif + } + if( cput <= 0.0 ) cput = 0.001; if( realt <= 0.0 ) realt = 0.001; fprintf(stdout, @@ -471,12 +611,22 @@ char **argv; trans?"-t":"-r", buf); } + free(alloc_buf); +#ifdef __rtems__ + return 0; +#else exit(0); +#endif usage: fprintf(stderr,Usage); + free(alloc_buf); +#ifdef __rtems__ + return 1; +#else exit(1); - return 0; + return 1; +#endif } void @@ -486,7 +636,16 @@ char *s; fprintf(stderr,"ttcp%s: ", trans?"-t":"-r"); perror(s); fprintf(stderr,"errno=%d\n",errno); + free(alloc_buf); + if (fd != 0) + { + close(fd); + } +#ifdef __rtems__ + return; +#else exit(1); +#endif } void @@ -540,10 +699,12 @@ double b; static struct timeval time0; /* Time at which timing started */ static struct rusage ru0; /* Resource utilization at the start */ +#ifndef __rtems__ static void prusage(); +static void psecs(); +#endif static void tvadd(); static void tvsub(); -static void psecs(); #if defined(SYSV) /*ARGSUSED*/ @@ -601,7 +762,11 @@ int len; getrusage(RUSAGE_SELF, &ru1); gettimeofday(&timedol, (struct timezone *)0); +#ifndef __rtems__ prusage(&ru0, &ru1, &timedol, &time0, line); +#else + line[0] = '\0'; +#endif (void)strncpy( str, line, len ); /* Get real time */ @@ -617,6 +782,7 @@ int len; return( cput ); } +#ifndef __rtems__ static void prusage(r0, r1, e, b, outp) register struct rusage *r0, *r1; @@ -731,6 +897,7 @@ prusage(r0, r1, e, b, outp) } *outp = '\0'; } +#endif static void tvadd(tsum, t0, t1) @@ -754,6 +921,7 @@ tvsub(tdiff, t1, t0) tdiff->tv_sec--, tdiff->tv_usec += 1000000; } +#ifndef __rtems__ static void psecs(l,cp) long l; @@ -777,6 +945,7 @@ register char *cp; *cp++ = ':'; sprintf(cp,"%d%d", i / 10, i % 10); } +#endif //!__rtems__ /* * N R E A D -- cgit v1.2.3