b0VIM 7.2PK`_{jfinkaltair~jfink/src/nettest/nettest.cutf-8 3210#"! Utp TU   % Y9 :nQadTmif"] O A | 6 I B `]<{x<[}2zvub6T6/~#include #ifndef NO_ISO#include #include #include #include #include #include #endif#include #if defined(BSD44) || defined(sun) || defined(ultrix) || defined(sgi)#endif#include #ifdef BSD44#include "nettest.h"#define SRCRT#endif#include #if defined(LINUX) All rights reserved.\n";"@(#) Copyright 1992 Cray Research, Inc.\n\char copyright[] = */ * POSSIBILITY OF SUCH DAMAGE. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JASON OR CONTRIBUTORS * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * THIS SOFTWARE IS PROVIDED BY JASON FINK AND CONTRIBUTORS * * from this software without specific prior written permission. * contributors may be used to endorse or promote products derived * 2. Neither the name of Jason Fink nor the names of * notice, this list of conditions and the following disclaimer. * 1. Redistributions of source code must retain the above copyright * are met: * modification, are permitted provided that the following conditions * Redistribution and use in source and binary forms, with or without * * Copyright 2006, 2008 Jason (Jay) R. Fink /* */ * PERFORMANCE OF THIS SOFTWARE. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * PARTICULAR PURPOSE. IN NO EVENT SHALL CRAY RESEARCH, INC. BE * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * THIS SOFTWARE IS PROVIDED AS IS AND CRAY RESEARCH, INC. * * way and is referred to as Nettest. * if no fee is charged); and 6) this software is not renamed in any * separate product (except that it may be redistibuted separately if * redistributed only as part of a bundled package and not as a * source and binary copies of this software; 5) the software is * binary copyright notice are retained without modification in all * specific prior written permission; 4) the USMID revision line and * endorse or promote products derived from this software without * this software; 3) the name Cray Research, Inc. may not be used to * and in all advertising materials mentioning features or use of * the documentation or other materials provided with the distribution * product includes software developed by Cray Research, Inc.'' in * including binaries display the following acknowledgement: ``This * software and its supporting documentation; 2) distributions * this permission notice appear in all source copies of this * hereby granted, provided that: 1) the above copyright notice and * source and binary forms, and its documentation, without fee is * Permission to use, copy, modify and distribute this software, in/* */ * All Rights Reserved. * Copyright 1992 Cray Research, Inc./*static char USMID[] = "@(#)tcp/usr/etc/nettest/nettest.c 80.6 11/03/92 17:12:29";adK QtmbTFBmj:.! n Z Y T > 1 # !   p i f W I 3 2 r S B = 9 #endif} return (tos); } return (-1); if (tos < MIN_TOS || tos > MAX_TOS) {#endif }#ifdef IP_TOS tos = (int)strtol(name, (char **)NULL, 0); } } return (-1); if (*c < '0' || *c > '9') { for (c = name; *c; c++) {#endif } else { tos = (int)tosp->t_tos; if (tosp) {#endif tosp = gettosbyname(name, proto);#ifndef LINUX tosp = (struct tosent *)gettosbyname(name, proto); struct tosent *tosp;#ifdef IP_TOS#undef IP_TOS */#endif tosp = gettosbyname(name, proto);#else tosp = (struct tosent *)gettosbyname(name, proto);#ifdef LINUX struct tosent *tosp;#ifdef IP_TOS /* int tos; register char *c;{ char *proto; char *name;parsetos(name, proto) int#define MAX_TOS 255#define MIN_TOS 0#ifndef HAS_PARSETOS#endif} return(sin_addr.s_addr); *lenp = lsrp - *cpp; *lsrp++ = IPOPT_NOP; /* 32 bit word align it */ } return((unsigned long)-1); *lenp = 0; *cpp = 0; if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) { } return((unsigned long)-1); if (lsrp + 4 > lsrep) */ * Check to make sure there is space for next address /* break; else cp = cp2; if (cp2) lsrp += 4; memcpy(lsrp, (char *)&sin_addr, 4); } return(0); *cpp = cp; } else {#endif memcpy((caddr_t)&sin_addr, host->h_addr, host->h_length);#else host->h_addr_list[0], host->h_length); memcpy((caddr_t)&sin_addr,adLYc^'"QED=9  o Z Y U  g <  h ?  | u [ E k Y H F E ? ,   vobM/ pAjUR ZF;8" sgcPF>;.NC@ i if (checkdata && !seqdata) bzero(cnts, (chunksize+1)*sizeof(long)); } exit(1); fprintf(stderr, "cannot malloc enough stats space\n"); if (cnts == NULL) { cnts = (long *)malloc((chunksize+1)*sizeof(long)); } exit(1); fprintf(stderr, "cannot malloc enough data space\n"); if (data == NULL) { orgdata = data = malloc(chunksize+8); exit(1); if (cp - buf > 1 && buf[0] == '0') printf("remote server: %s\n", &buf[1]); if (cp - buf > 2) *cp = '\0'; } cp++; break; if (*cp == '\n') } exit(1); fprintf(stderr, "nettest: Read returned %d, expected 1\n", i); else perror("read (waiting to verify setup)"); if (i < 0) if (i != 1) { i = read(in, cp, 1); for (cp = buf; ; ) { } exit(1); perror("write1"); if (write(out, buf, strlen(buf)) != strlen(buf)) {#endif waitall = 0; /* so we don't screw up the recv() */#ifndef MSG_WAITALL kbufsize, tos, nodelay, seqdata, waitall); sprintf(buf, "%d %d %d %d %d %d %d %d\n", nchunks, chunksize, fullbuf, } chunksize &= ~0x7; chunksize, chunksize & ~0x7); printf("data size must be multiple of 8. %d rounded to %d\n", if (seqdata && chunksize&0x7) {#endif /* NO_ISO */ } } exit(1); fprintf(stderr, "read(ISO CC) failed\n"); if ((i = read(in, buf, sizeof(buf))) != 0) { if (domain == D_ISO) { /* rea register unsigned int loval; register unsigned int register unsigned int loval; register unsigned int hival;#ifndef CRAY TIMETYPE start, turnaround, end; struct tms tms1, tms2, tms3; register long *ldp; long *cnts;#endif char buf[128], *data, *malloc(), *orgdata;#else char buf[128], *data, *orgdata;#ifdef LINUX register char *cp; register int i, t, j, offset = 0, t2;{ register int in, out;do_stream(in, out) void} return(retval); retval *= 1024; if (*s == 'k' || *s == 'K') ++s; while (*s >= '0' && *s <= '9') retval = atoi(s); register int retval;{ register char *s;atoval(s) int} return(1); /* indicate that we extracted the timing information */ *cendp = tms.mt_end; *cstartp = tms.mt_start;#endif *endp = tms.mt_end; if (tms.mt_end > *endp) *startp = tms.mt_start; if ((tms.mt_start < *startp) || (*startp == 0))#else *endp = tms.mt_end; (tms.mt_end.millitm > endp->millitm))) ((tms.mt_end.time == endp->time) && if ((tms.mt_end.time > endp->time) || *startp = tms.mt_start; ((startp->time == 0) && (startp->millitm == 0))) (tms.mt_start.millitm < startp->millitm)) || ((tms.mt_start.time == startp->time) && if ((tms.mt_start.time < startp->time) ||#if !defined(CRAY) && !defined(SYSV) tmsp->tms_stime += tms.mt_tms.tms_stime; tmsp->tms_utime += tms.mt_tms.tms_utime; */ * time if it is later than what we've gotten so far. * Add in the timing information, and update the ending /* *np -= sizeof(tms); bcopy(c1 + sizeof(tms), c1, *np - (c1 + sizeof(tms) - buf)); bcopy(c1, (char *)&tms, sizeof(tms)); */ * adjust the length value that was passed in. * Pull the timing data out of the buffer, and /*gotit: return(0); /* indicate that we did not get timing information */ } } goto gotit; if (strncmp(c1, UT_MAGIC, 8) == 0) { continue; if (*c1 != UT_MAGIC[0]) */ * Quick check to aviod overhead of strncmp() /* for (c1 = buf; c1 <= buf + *np - sizeof(tms); c1++) { */ * designates the beginning of the timing information. * Scan the buffer for the magic string that /* register char *c1; static struct magic_tms tms;adnmaTHA@*%lkJ9" x q l h 9    o n c E D 8 +    u q a - #    y p b K F ;    w h b O :    |KmUPH84 U1pYC>2+'lg2wD strncpy(td.mt_magic, UT_MAGIC, 8); struct magic_tms td; */ * split across read()s. * won't have to worry about this data getting * of the data read by the master client, and it * statistics, so that it it will be at the beginning * Note that we do this before printing out the * * the data transfer. * a magic cookie and then the time it took to do * We are a slave of the master client. Write out /* if (sync_children) { GETTIMES(end, tms3); } } data = orgdata + t;#endif *(((long *)orgdata) + 1) = *(ldp+1);#ifndef CRAY *(long *)orgdata = *ldp; if (t) { t -= j*8; }#endif ++loval; } loval = *(ldp-1); loval, *(ldp-1)); printf("expected %16x, got %16x\n", if (*ldp++ != loval) {#else ++hival; if (++loval == 0) } loval = ntohl(*(ldp-1)); hival = ntohl(*(ldp-2)); ntohl(*(ldp-1))); hival, loval, ntohl(*(ldp-2)), printf("expected %8x%8x, got %8x%8x\n", if ((ntohl(*ldp++) != loval) || t2) { t2 = ntohl(*ldp++) != hival;#ifndef CRAY for (j = 0; j < t/8; j++) { ldp = (long *)data; data = orgdata; t += data - orgdata; } continue; } } ((j+t2)/8)%32)); *("abcdefghijklmnopqrstuvwxyzABCDEF" + i, (j+t2), i*chunksize + (j+t2), *cp, fprintf(stderr, "%d/%d(%d): got %d, expected %d\n", ((j+t2)/8)%32)) { if (*cp != *("abcdefghijklmnopqrstuvwxyzABCDEF" + for (cp = data, j = 0; j < t; cp++, j++) { if (!seqdata) { continue; if (!checkdata) } t2 = 0; write(1, "#", 1); if (hash) } t += t2; cnts[t2]++; } break; "EOF on file, block # %d\n", i); fprintf(stderr, if (t2 == 0) { } goto bad; chunksize-t); sprintf(buf, "read #%d.%d", i, waitall)) < 0) { if ((t2 = (*rfunc)(in, data+t, chunksize-t, write(1, ".", 1); if (hash) while (t != chunksize) { } else { } write(1, ".", 1); if (hash) --i; } else { write(1, "#", 1); if (hash) offset -= chunksize; if (offset >= chunksize) { offset += t; t2 = offset; if (fullbuf) { cnts[t]++; } break; fprintf(stderr, "EOF on file, block # %d\n", i); if (t == 0) { } goto bad; sprintf(buf, "read #%d.%d", i+1, chunksize); if ((t = (*rfunc)(in, data, chunksize, waitall)) < 0) { for (i = 0; i < nchunks || offset; i++) {#endif hival = 0;#ifndef CRAY loval = 0; write(0, "\r\nRead: ", 9); if (hash) GETTIMES(turnaround, tms2); } write(1, "#", 1); if (hash) fprintf(stderr, "write: %d got back %d\n", chunksize, t); if (t != chunksize) } goto bad; sprintf(buf, "write #%d:", i+1); if ((t = write(out, data, chunksize)) < 0) { } }#endif *ldp++ = loval++;#else ++hival; if (++loval == 0) *ldp++ = htonl(loval); *ldp++ = htonl(hival);#ifndef CRAY for (j = 0; j < chunksize/8; j++) { ldp = (long *)data; if (seqdata) { for (i = 0; i < nchunks; i++) { GETTIMES(start, tms1); } kill(getpid(), SIGSTOP); /* suspend ourself */ */ * will restart us. * are ready to go. The master client * Don't start until all the children /* if (sync_children) {#endif hival = 0;#ifndef CRAY loval = 0; write(0, "\r\nWrite: ", 9); if (hash) *cp++ = *("abcdefghijklmnopqrstuvwxyzABCDEF" + (i++/8)%32); for (cp = data, i = 0; i < chunksize; )adErV?,  p]K@;7/ k h T K F 8 . , + %   e " u d b L 6 (   S H E D .  x ` _ ^ R 1  ud]\K j]ZYCB>vUSDCa.'x5vR5 hE (chunksize*nchunks)/(125.0*t1)); (chunksize*nchunks)/(128.0*1024.0*(t1/1000.0)), (chunksize*nchunks)/(1024.0*(t1/1000.0)), (float)tms1->tms_utime/t1*100000.0/HZ, (float)tms1->tms_utime/HZ, (float)tms1->tms_stime/t1*100000.0/HZ, (float)tms1->tms_stime/HZ, printf(FORMAT, "write", t1/1000.0, if (t1 && p2)#define FORMAT "%7s %7.4f %7.4f (%4.1f%%) %7.4f (%4.1f%%) %7.2f %7.3f %7.3f\n" printf(" Real System User Kbyte Mbit(K^2) mbit(1+E6)\n"); tms2->tms_stime = tms3 ? (tms3->tms_stime - tms2->tms_stime) : 0; tms2->tms_utime = tms3 ? (tms3->tms_utime - tms2->tms_utime) : 0; tms1->tms_stime = tms2->tms_stime - tms1->tms_stime; tms1->tms_utime = tms2->tms_utime - tms1->tms_utime;#endif t2 = (p2 ? ((float)(*p2 - *p1)*1000.0/HZ) : 0.0); t1 = (float)(*p1 - *p0)*1000.0/HZ;#else + p2->millitm - p1->millitm) : 0.0); t2 = (p2 ? ((p2->time - p1->time)*1000L + p1->millitm - p0->millitm; t1 = (p1->time - p0->time)*1000L#if !defined(CRAY) && !defined(SYSV) float t1, t2;{ struct tms *tms1, *tms2, *tms3; TIMETYPE *p0, *p1, *p2;prtimes(p0, p1, p2, tms1, tms2, tms3) void} prtimes(&start, &end, &end, &tms1, &tms2, &tms2); */ * Pass in same middle and end times because we only do writes for udp. /* GETTIMES(end, tms2); } (*data)++; mesghdr ? "sendmsg" : "sendto", ret, chunksize); printf("%s returned %d, expected %d\n", if (ret != chunksize) } exit(1); printf("%d out of %d sent\n", i, nchunks); perror(mesghdr ? "sendmsg" : "sendto"); if (ret < 0) {#endif namesize); : sendto(s, data, chunksize, 0, (caddr_t)&name,#else (struct sockaddr *)&name, namesize); : sendto(s, data, chunksize, 0,#ifdef LINUX ret = mesghdr ? sendmsg(s, &outmsg, 0) for (i = 0; i < nchunks; i++) { *data = 0; GETTIMES(start, tms1); outmsg.msg_namelen = namesize; outmsg.msg_name = (caddr_t)&name; outmsg.msg_iovlen = 1; outmsg.msg_iov = &iov; bzero((char *)&outmsg, sizeof(outmsg)); iov.iov_len = chunksize; iov.iov_base = data; } exit(1); fprintf(stderr, "cannot malloc enough space\n"); if (data == NULL) { data = malloc(chunksize); struct iovec iov; struct msghdr outmsg; TIMETYPE start, end; struct tms tms1, tms2;#endif char *malloc();#ifndef LINUX register char *data; register int ret, i;{ register int s;do_dgram(s) void} exit(1);" nettest -V\n");" nettest [-cdfh] [-b bufsize] -p file file1 file2 [count [size]]"," [count [size [filename]]]"," nettest [-cdfh] [-b bufsize] -p unix|pipes [-n #streams]"," [-p tcp|udp|iso] [host [count [size [port]]]]","Usage: nettest [-cdfFh] [-b bufsize] [-s winshift] [-S tos] [-n #streams]", fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",{usage() void} exit(1); perror(buf);bad: return;#endif /* NO_ISO */ } sleep(1); /* wait for packet to reach server */ write(out, data, 4); strncpy(data, "DONE", 4); if (domain == D_ISO) { /* send out ISO sync data to server */#ifndef NO_ISO printf("\n"); if (j) } } j = 0; printf("\n"); if (++j == 4) { printf("%6d: %5ld ", i, cnts[i]); if (cnts[i]) { for (i = 0; i <= chunksize; i++) j = 0; prtimes(&start, &turnaround, &end, &tms1, &tms2, &tms3); } write(1, &td, sizeof(td)); td.mt_end = end; td.mt_start = start; td.mt_tms.tms_cstime = 0; td.mt_tms.tms_cutime = 0; td.mt_tms.tms_stime = tms3.tms_stime - tms1.tms_stime; td.mt_tms.tms_utime = tms3.tms_utime - tms1.tms_utime;adDh?m< U  ` 8   ~ { m C @   [ X F C ` (   yv<! u[7%$ gJFwtshgc3y\["  xcW=*XD#if defined(h_addr) } else if (host = gethostbyname(cp)) { sin_addr.s_addr = tmp; if ((tmp = inet_addr(cp)) != -1) { cp2 = 0; if (!c) } break; continue; } else *cp2++ = '\0'; } else if (c == ':') { *cp2++ = '\0'; } else if (c == '@') { cp2++; if (*cp2 == '@') *cp2++ = '\0'; if (c == ',') { else for (cp2 = cp; c = *cp2; cp2++) { cp2 = 0; if (c == ':') for (c = 0;;) { sin_addr.s_addr = 0; cp++; *lsrp++ = 4; lsrp++; /* skip over length, we'll fill it in later */ return((unsigned long)-1); if (*cp != '@') *lsrp++ = IPOPT_LSRR; } else *lsrp++ = IPOPT_SSRR; cp++; if (*cp == '!') { */ * the begining of the option. * route or a strict source route, and fill in * Next, decide whether we have a loose source /* cp = arg; } lsrep = lsrp + 44; *cpp = lsrp = lsr; } else { lsrep = lsrp + *lenp; lsrp = *cpp; if (*cpp) { */ * or if we need to use our own static buffer. * Decide whether we have a buffer passed to us, /* return((unsigned long)-1); if (*cpp != NULL && *lenp < 7) return((unsigned long)-1); if (cpp == NULL || lenp == NULL) */ * at least 7 bytes for the option. * Verify the arguments, and make sure we have /* register char c; register struct hostent *host = 0; struct in_addr sin_addr; register int tmp; char *cp, *cp2, *lsrp, *lsrep, *index(); static char lsr[44];{ int *lenp; char **cpp; char *arg;sourceroute(arg, cpp, lenp) unsigned long */ * * pointed to by *cpp is. * *lenp: This will be filled in with how long the option * * the option filled in. This will be 32bit aligned. * in with a pointer to our static area that has * *cpp: If *cpp was equal to NULL, it will be filled * * hostname. * path is unknown, and *cpp is set to point to the bad * If the return value is 0, one of the hostnames in the * option, either unknown characters, or too many hosts. * return value is -1, there was a syntax error in the * Returns the address of the host to connect to. If the * * Return values: * * length of *cpp if *cpp != NULL. * lenp: pointer to an integer that contains the * * that should be filled in with the option. * pointer to a pointer to a character array * cpp: If *cpp is not equal to NULL, this is a * * arg: pointer to route list to decipher * Arguments: * * be the address to connect() to. * and return a pointer to hop1, which will * hop1,hop2,hop3...dest * We fill in the source route option as * * assmed to be a loose source route. * strict source route, otherwise it is * If the leading ! is present, it is a * [!]@hop1@hop2...[@|:]dst * Source route is handed in as/*#if defined(SRCRT) && defined(IPPROTO_IP)} (chunksize*nchunks)/(62.5*(t1 + t2))); (chunksize*nchunks)/(64.0*1024.0*((t1 + t2)/1000.0)), (chunksize*nchunks)/(512.0*((t1 + t2)/1000.0)), (float)(tms1->tms_utime + tms2->tms_utime)/(t1+t2)*100000.0/HZ, (float)(tms1->tms_utime + tms2->tms_utime)/HZ, (float)(tms1->tms_stime + tms2->tms_stime)/(t1+t2)*100000.0/HZ, (float)(tms1->tms_stime + tms2->tms_stime)/HZ, printf(FORMAT, "r/w", (t2+t1)/1000.0, if ((t1 && t2) || (!p2 && (t1 + t2))) (chunksize*nchunks)/(125.0*t2)); (chunksize*nchunks)/(128.0*1024.0*(t2/1000.0)), (chunksize*nchunks)/(1024.0*(t2/1000.0)), (float)tms2->tms_utime/t2*100000.0/HZ, (float)tms2->tms_utime/HZ, (float)tms2->tms_stime/t2*100000.0/HZ, (float)tms2->tms_stime/HZ, printf(FORMAT, "read", t2/1000.0, if (t2 && p2)ad(n]L;+*" |gfD! | v h a <  u n e T G 0 u t D C 4  q Z N > 7 6    s Y P B * ~rXI3,WJ<mE7-lYKE tf\)  fprintf(stderr, if (nconnections < 1 || nconnections > maxchildren) { nconnections = atoi(optarg); case 'n': /* # connections to the destination */ break; ++mesghdr; case 'm': /* use sendmsg() instead of sendto() */ break; ++hash; case 'h': /* show progress of data transfer */ break;#endif usage(); fprintf(stderr, "TCP nodelay option not supported\n");#else nodelay++;#ifdef TCP_NODELAY case 'F': /* turn off the NODELAY bit for TCP */ break; fullbuf++; case 'f': /* always post full buffers for reads */ break; dflag++; case 'd': /* turn on socket debugging */ break; ++seqdata; ++checkdata; /* implies -c option */ case 'C': /* use a sequential data pattern */ break; ++checkdata; case 'c': /* check the data for correctness */ break; kbufsize = atoval(optarg); case 'b': /* kernel socket buffer size */ switch(i) { while ((i = getopt(argc, argv, "b:cCdfFhmn:p:s:S:t:Vw?")) != EOF) { maxchildren = getdtablesize() - 4; */ * to get the maximum number of children. * subract 4 from the maximum number of file descriptors * file descriptor for when we create the pipe. So, we * per child, plus stdin/stdout/stderr, plus one extra * created. We assume that we will have one pipe open * Set max children to allow for all the pipes to be /* extern int optind; extern char *optarg;#endif struct hostinfo *hi; } portnumber; char data[sizeof(int)]; int port; union { struct sockaddr_iso *to = &to_s;#ifndef NO_ISO#endif unsigned long sourceroute(), srlen; char *srp = 0, *strrchr();#if defined(SRCRT) && defined(IPPROTO_IP) int nconnections = 1; int on = 1; int i; int type = SOCK_STREAM; register char *portname = 0; char *destname; struct hostent *gethostbyname(), *hp; register int s, s2, port = PORTNUMBER;{ char **argv; int argc;main(argc, argv)int (*rfunc)() = read;#endifssize_t recv();int read();int read(), recv(); *//* XXX-jrf From FreeBSD ports patch-ab#elseint read();#ifdef LINUXvoid do_children(), do_stream(), usage(), do_dgram(), prtimes();#endifstruct sockaddr_iso to_s = {sizeof(to_s), AF_ISO};#ifndef NO_ISOchar *hisname, _myname[256], *myname = _myname;struct in_addr hisaddr;}; TIMETYPE mt_end; TIMETYPE mt_start; struct tms mt_tms; char mt_magic[8];struct magic_tms {char UT_MAGIC[8] = { 'U', 't', 'i', 'm', 'e', 's', '.', '.' };int sync_children = 0;int waitall;int maxchildren;int tos;#endifint usewinshift;int winshift;#ifdef TCP_WINSHIFT#endif#define TIMETYPE long#define GETTIMES(a, b) a = times(&b);#else#define TIMETYPE struct timeb#define GETTIMES(a, b) ftime(&a); times(&b);#if !defined(CRAY) && !defined(SYSV)#endiflong times();#elseclock_t times();#ifdef BSD44int mesghdr = 0;int nodelay = 0;int kbufsize = 0;int fullbuf = 0;int hash = 0;int seqdata = 0;int checkdata = 0;int dflag = 0;int chunksize = CHUNK; /* 4096 */int nchunks = NCHUNKS; /* 100 */int domain = D_INET;int namesize;} name;#endif /* NO_ISO */ struct sockaddr_iso d_iso;#ifndef NO_ISO struct sockaddr_un d_unix; struct sockaddr_in d_inet; struct sockaddr d_gen;union {#define D_ISO 5#define D_FILE 4#define D_INET 3#define D_UNIX 2#define D_PIPE 1#endif# endif# define HZ CLK_TCK# ifndef HZ# include #ifdef CRAY#endif /* NO_ISO */#include adaL4 ye=( k T +  e X S I   g Z U O    ] $      y J > =  oE}>|ZHHB \A2 uaS8#  if (argc) { } argc -= 2; hisname = *argv++; myname = *argv++; usage(); if (argc < 2) } else if (domain == D_FILE) { } --argc; ++argv; hisname = *argv; if (strcmp(*argv, "-")) if (argc) { hisname = myname; if ((domain == D_INET) || (domain == D_ISO)) { */ * Pick up the port/file name(s) /* } );#endif "tcp, unix, pipe, and file"#else "tcp, iso, unix, pipe, and file"#ifndef NO_ISO seqdata ? 'C' : 'c', fprintf(stderr, "-%c flag ignored (only valid for %s)\n", (type != SOCK_STREAM)) {#endif (type != SOCK_SEQPACKET) &&#ifndef NO_ISO if (checkdata && } );#endif "-w flag ignored (only valid for tcp and unix)\n"#else "-w flag ignored (only valid for tcp, iso and unix)\n"#ifndef NO_ISO fprintf(stderr, (type == SOCK_DGRAM))) { (domain == D_FILE) || if (waitall && ((domain == D_PIPE) || } tos = 0; "tos value ignored (only valid for tcp and udp)\n"); fprintf(stderr, if (tos && (domain != D_INET)) { } "-m flag ignored (only valid for udp and unixd\n"); fprintf(stderr, if (mesghdr && (type != SOCK_DGRAM)) { } nodelay = 0; fprintf(stderr, "-F flag ignored (only valid for tcp\n"); if (nodelay && ((domain != D_INET) || type != SOCK_STREAM)) { */ * Verify consitency of the specified options /* argv += optind; argc -= optind; } } usage(); default: case '?': break;#endif waitall = 1; /* will be re-set to 0 below */ "but will be passed on to server."); "MSG_WAITALL (-w) not supported locally, ", fprintf(stderr, "%s%s\n",#else rfunc = (void *)recv; waitall = MSG_WAITALL;#ifdef MSG_WAITALL case 'w': /* use the MSG_WAITALL flag on recv() */ exit(0); printf("%s\n%s", &USMID[4], ©right[4]); case 'V': /* Print the version of this program */#endif usage(); fprintf(stderr, "TOS (-%c) option not supported\n", (char)i);#else break; } usage(); fprintf(stderr, "Bad tos argument: '%s'\n", optarg); if ((tos = parsetos(optarg, "*")) < 0) {#ifdef IP_TOS case 't': /* old flag for setting TOS... */ case 'S': /* Set the IP Type-of-Service bits */ break;#endif usage(); fprintf(stderr, "window shift option not supported\n");#else } usage(); fprintf(stderr, "window shift (-s) must be beteen -1 and 14\n"); if (winshift < -1 || winshift > 14) { winshift = atoi(optarg); usewinshift++;#ifdef TCP_WINSHIFT case 's': /* Use the TCP window shift option */ break; } usage(); fprintf(stderr, "Unknown protocol: %s\n", optarg); } else { type = SOCK_STREAM; domain = D_FILE; } else if (!strcmp(optarg, "file")) { type = SOCK_STREAM; domain = D_PIPE; } else if (!strcmp(optarg, "pipe")) { type = SOCK_DGRAM; domain = D_UNIX; } else if (!strcmp(optarg, "unixd")) { type = SOCK_STREAM; domain = D_UNIX; } else if (!strcmp(optarg, "unix")) { nchunks = 1; type = SOCK_DGRAM; domain = D_INET; } else if (!strcmp(optarg, "udp")) {#endif /* NO_ISO */ usage(); fprintf(stderr, "iso protocol not supported\n");#else /* NO_ISO */ type = SOCK_SEQPACKET; domain = D_ISO;#ifndef NO_ISO } else if (!strcmp(optarg, "iso")) { type = SOCK_STREAM; domain = D_INET; if (!strcmp(optarg, "tcp")) { case 'p': /* protocol to use */ break; } usage(); maxchildren); "-n: value must be between 1 and %d\n",ad p]N0e-! k X J > : 1 # z v ^ O ; / + "  v 6   y u S /  p J ; /  h<-PBA#uoOH<c\WS-yVIDeF2) if (dflag) } exit(1); perror("socket"); if (s < 0) { s = socket(name.d_gen.sa_family, type, 0); do_children(nconnections); if (nconnections > 1) dosock:#endif /* NO_ISO */ TSEL(&(name.d_iso)), 2); bcopy(&(portnumber.data[(sizeof(int)-2)]), portnumber.port = htons(port); name.d_iso.siso_tlen = 2; namesize = sizeof(name.d_iso); name.d_iso = *to; } to = (struct sockaddr_iso *)(*hi->h_addr_serv)->hs_addr; } exit(1); perror("gethostinfo(AF_ISO)"); if ((hi = gethostinfo(hisname, 0, AF_ISO, 0, 0)) == 0) { if (hisname != myname) { gethostname(_myname, sizeof(_myname)); case D_ISO:#ifndef NO_ISO break; goto dosock; name.d_inet.sin_port = htons(port); } }#endif name.d_inet.sin_addr = tmp; bcopy(hp->h_addr, (char *)&tmp, hp->h_length); long tmp;#else hp->h_length); bcopy(hp->h_addr, (char *)&name.d_inet.sin_addr,#if !defined(CRAY) || defined(s_addr) } else {#endif name.d_inet.sin_addr = tmp;#else name.d_inet.sin_addr.s_addr = tmp;#if !defined(CRAY) || defined(s_addr) } exit(1); fprintf(stderr, "no host entry fo %s\n", hisname); if (tmp == -1) { tmp = inet_addr(hisname); long tmp; if ((hp = gethostbyname(hisname)) == NULL) {#endif } else { }#endif name.d_inet.sin_addr = temp;#else name.d_inet.sin_addr.s_addr = temp;#if !defined(CRAY) || defined(s_addr) } else { return 0; hisname); printf("Bad source route option: %s\n", } else if (temp == -1) { return 0;#endif printf("Can't get source route: %s\n", srp);#else herror(srp);#ifndef sun if (temp == 0) { temp = sourceroute(hisname, &srp, &srlen); srp = 0; destname++; destname = strrchr(hisname, '@'); if ((destname = strrchr(hisname, ':')) == NULL) int temp; if (*hisname == '@' || *hisname == '!') {#if defined(SRCRT) && defined(IPPROTO_IP) gethostname(_myname, sizeof(_myname)); name.d_inet.sin_family = AF_INET; namesize = sizeof(name.d_inet); } usage(); fprintf(stderr, "-n flag not supported for udp\n"); if (nconnections > 1 && type != SOCK_STREAM) { case D_INET: break; goto dosock; + strlen(name.d_unix.sun_path); namesize = sizeof(name.d_unix) - sizeof(name.d_unix.sun_path) strcpy(name.d_unix.sun_path, portname); name.d_unix.sun_family = AF_UNIX; portname = (type == SOCK_DGRAM) ? UNIXDPORT : UNIXPORT; if (portname == 0) case D_UNIX: break; } exit(1); perror(hisname); if (s < 0) { s = open(hisname, 0); } exit(1); perror(myname); if (s2 < 0) { s2 = open(myname, 1); } usage(); fprintf(stderr, "-n flag not supported for file\n"); if (nconnections > 1) { case D_FILE: break; } exit(1); close(s2); perror(myname); if ((s = open(myname, 0)) < 0) { sprintf(myname, "%sR", portname); } exit(1); perror(myname); if ((s2 = open(myname, 1)) < 0) { sprintf(myname, "%sW", portname); } usage(); fprintf(stderr, "-n flag not supported for pipe\n"); if (nconnections > 1) { portname = PIPENAME; if (portname == 0) case D_PIPE: switch(domain) { } } } usage(); if (argc > 1) } portname = *argv; port = atoi(*argv); if (strcmp(*argv, "-")) { if (argc) { --argc; ++argv; chunksize = atoval(*argv); if (strcmp(*argv, "-")) if (argc) { --argc; ++argv; nchunks = atoval(*argv); if (strcmp(*argv, "-"))adZ=v?! n 3  g ? ; 4 o _ L @ < u o > 7 !    e _ O N ; -    c5 QPMvXTN4!oYH98d4i^[.-j`ZY /* case 0: switch(n = fork()) { } continue; CHILD_READ(i) = -1; fprintf(stderr, "Cannot create pipe for child %d\n", i); if (pipe(&CHILD_READ(i)) < 0) { for (i = 0; i < nconnections; i++) { bzero(childrenp, ARRAY_SIZE(nconnections)); } exit(1); "malloc() for data to keep track of children failed\n"); fprintf(stderr, if (childrenp == NULL) { childrenp = (struct children *)malloc(ARRAY_SIZE(nconnections)); } sync_children = getpgrp(); (void) setpgid(sync_children, sync_children); if (sync_children != getpgrp()) { sync_children = getpid(); bzero((char *)&tms2, sizeof(tms2)); bzero((char *)&tms1, sizeof(tms1)); bzero((char *)&end, sizeof(end)); bzero((char *)&start, sizeof(start)); int gottimes; char buf[1024]; TIMETYPE start, end; struct tms tms1, tms2; int notready = 0, nchildren; int status, child_error = 0;#endif char *malloc();#ifndef LINUX struct children *childrenp; int n; register int i;{ int nconnections;do_children(nconnections) void */ * a pipe set up beforehand). * for the children to die, printing out their statistics (read off of * return in each of the children. The parent program will hang around * When called, this routine will fork off "nconnections" children, and/*#define ARRAY_SIZE(n) ((n)*sizeof(struct children))#define CHILD_END(n) (childrenp[n].c_end)#define CHILD_START(n) (childrenp[n].c_start)#define CHILD_READY(n) (childrenp[n].c_ready)#define CHILD_PID(n) (childrenp[n].c_pid)#define CHILD_WRITE(n) (childrenp[n].c_write)#define CHILD_READ(n) (childrenp[n].c_read)}; TIMETYPE c_start, c_end; int c_ready; int c_pid; int c_write; int c_read;struct children {} } close(s2); close(s); else { shutdown(s, 2); if (s == s2) do_stream(s, s2); printf("\n"); else printf(" from %9s to %9s\n", myname, hisname); if ((domain == D_INET) || (domain == D_ISO)) printf("Transfer: %d*%d bytes", nchunks, chunksize); } break; s2 = s; } exit(1); perror("connect");#endif if (connect(s, (char *)&name, namesize) < 0) {#else if (connect(s, (struct sockaddr *)&name, namesize) < 0) {#ifdef LINUX * need to check with FreeBSD7 and NetBSD3 at some point *//* XXX-jrf This may work for all modern unices now - not sure ... } exit(0); shutdown(s, 2); do_dgram(s); if (type == SOCK_DGRAM) {#endif perror("setsockopt (IP_OPTIONS)"); (char *)srp, srlen) < 0) if (srp && setsockopt(s, IPPROTO_IP, IP_OPTIONS,#if defined(SRCRT) && defined(IPPROTO_IP)#endif } perror("setsockopt - TCP_NODELAY"); sizeof(nodelay)) < 0) if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &nodelay, if (nodelay) {#ifdef TCP_NODELAY#endif } perror("setsockopt - TCP_WINSHIFT"); sizeof(winshift)) < 0) if (setsockopt(s, IPPROTO_TCP, TCP_WINSHIFT, &winshift, if (usewinshift) {#ifdef TCP_WINSHIFT }#endif /* SO_SNDBUF */ printf("-b: cannot set local buffer sizes\n");#else /* !SO_SNDBUF */ perror("setsockopt - SO_RCVBUF"); sizeof(kbufsize)) < 0) if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &kbufsize, perror("setsockopt - SO_SNDBUF"); sizeof(kbufsize)) < 0) if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &kbufsize,#ifdef SO_SNDBUF if (kbufsize) {#endif perror("setsockopt - IP_TOS"); if (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) if (tos)#ifdef IP_TOS perror("setsockopt - SO_DEBUG"); if (setsockopt(s, SOL_SOCKET, SO_DEBUG, &on, sizeof(on)) < 0)adEw[@;p?54) e K @ < ! m Z T 8   { _ Y < % z j . H 6 !    uc"nhXhN3&%a,&sB?>421.~HsGED{ TIMETYPE *startp, *endp, *cstartp, *cendp; struct tms *tmsp; int *np; char *buf;extract_times(buf, np, tmsp, startp, endp, cstartp, cendp) int */ * split across read()s it will not be extracted. * information, or we get none of it. If the data is * This routine assumes that if we get all the timing * * extracted from the buffer. * inicate whether or not timing information was * data stream. It returns non-zero or zero to * Extract client timing information from the/*} exit(0); } duration/1000.0, (offset + duration)/1000.0); printf("%5d: %8.4f %8.4f %8.4f\n", i, offset/1000.0,#endif duration = (float)(CHILD_END(i) - CHILD_START(i))*1000.0/HZ; offset = (float)(CHILD_START(i) - start)*1000.0/HZ;#else + CHILD_END(i).millitm - CHILD_START(i).millitm; duration = (CHILD_END(i).time - CHILD_START(i).time)*1000L + CHILD_START(i).millitm - start.millitm; offset = (CHILD_START(i).time - start.time)*1000L#if !defined(CRAY) && !defined(SYSV) continue; if (CHILD_READY(i) == 0) float offset, duration; for (i = 0; i < nconnections; i++) { printf("Child: Start Duration End\n"); printf("\nSyncronization information:\n"); prtimes(&start, &end, 0, &tms1, &tms2, 0); nchunks *= nchildren; /* for total amount of data transfered */ printf("\n"); else printf(" from %9s to %9s\n", myname, hisname); if ((domain == D_INET) || (domain == D_ISO)) nchunks, chunksize, nchildren); printf("Transfer: %d*%d bytes over %d streams", printf(" (May not be accurate due to errors in children)\n"); if (child_error) nchildren, nconnections); printf("Aggregate statistics for %d of %d children:\n", printf("--------------------\n"); */ * Print the aggregate statistics. /* } CHILD_PID(i) = -1; child_error++; if (!gottimes || !WIFEXITED(status) || WEXITSTATUS(status)) close(CHILD_READ(i)); } (void) write(1, buf, n); if (n > 0) &CHILD_START(i), &CHILD_END(i)); gottimes += extract_times(buf, &n, &tms2, &start, &end, while ((n = read(CHILD_READ(i), buf, sizeof(buf))) > 0) { gottimes = 0; fflush(stdout); printf("Child %d statistics:\n", i); */ * Print out the childs statistics. /* } killpg(sync_children, SIGCONT); if (--notready == 0) CHILD_READY(i) = 1; if (CHILD_READY(i) == 0) { */ * suspending themselves. * Check for children that have died before /* } continue; } killpg(sync_children, SIGCONT); if (--notready == 0) CHILD_READY(i) = 1; if (CHILD_READY(i) == 0) { if (WIFSTOPPED(status)) { */ * fire them up. * stopped, send the SIGCONT to all of them to * Check for stopped children. When they are all /* } continue; fprintf(stderr, "Unknown child [pid %d] died.\n", n); if (i == nconnections) { } break; if (CHILD_PID(i) == n) for (i = 0; i < nconnections; i++) { while ((n = waitpid(-1, &status, WUNTRACED)) >= 0) { nchildren = notready; } } break; notready++; CHILD_PID(i) = n; close(CHILD_WRITE(i)); default: break; fprintf(stderr, "Child %d not started\n", i); CHILD_WRITE(i) = -1; close(CHILD_WRITE(i)); CHILD_READ(i) = -1; close(CHILD_READ(i)); case -1: return; close(CHILD_WRITE(i)); dup2(CHILD_WRITE(i), 2); dup2(CHILD_WRITE(i), 1); } close(CHILD_READ(n)); if (CHILD_READ(n) >= 0) for (n = 0; n <= i; n++) { */ * our pipe to stdout and stderr, and return. * In the child. Close down all the pipes, dupad :`3'#  tq) y e Z W A *  o e ] Z M :  m b _ +  if (checkdata && !seqdata) bzero(cnts, (chunksize+1)*sizeof(long)); } exit(1); fprintf(stderr, "cannot malloc enough stats space\n"); if (cnts == NULL) { cnts = (long *)malloc((chunksize+1)*sizeof(long)); } exit(1); fprintf(stderr, "cannot malloc enough data space\n"); if (data == NULL) { orgdata = data = malloc(chunksize+8); exit(1); if (cp - buf > 1 && buf[0] == '0') printf("remote server: %s\n", &buf[1]); if (cp - buf > 2) *cp = '\0'; } cp++; break; if (*cp == '\n') } exit(1); fprintf(stderr, "nettest: Read returned %d, expected 1\n", i); else perror("read (waiting to verify setup)"); if (i < 0) if (i != 1) { i = read(in, cp, 1); for (cp = buf; ; ) { } exit(1); perror("write1"); if (write(out, buf, strlen(buf)) != strlen(buf)) {#endif waitall = 0; /* so we don't screw up the recv() */#ifndef MSG_WAITALL kbufsize, tos, nodelay, seqdata, waitall); sprintf(buf, "%d %d %d %d %d %d %d %d\n", nchunks, chunksize, fullbuf, } chunksize &= ~0x7; chunksize, chunksize & ~0x7); printf("data size must be multiple of 8. %d rounded to %d\n", if (seqdata && chunksize&0x7) {#endif /* NO_ISO */ } } exit(1); fprintf(stderr, "read(ISO CC) failed\n"); if ((i = read(in, buf, sizeof(buf))) != 0) { if (domain == D_ISO) { /* read ISO CC - 0 bytes */#ifndef NO_ISO#endif register unsigned long loval;#else