BBN-Vax-TCP/src/util/tcptest.c

Compare this file to the similar file:
Show the results in this format:

#define BBNNET
#include "netlib.h"
#include "net.h"
#include "con.h"
#include <sys/types.h>
#include <sys/timeb.h>
#include <signal.h>
#include <errno.h>

#define TRUE 1
#define FALSE 0
extern int errno;
extern char *progname;
struct con con;
struct netstate outstat;
struct timeb stime, ttime;
int timer;
int fr, fw, finis, loop, match, compare;
short wport, rport, host, imp, eol;
char *dir;
char outbuf[1024];
char inbuf[1024];
long bytes, ibytes;
float totals, itotals;

main(argc, argv)
int argc;
char *argv[];
{
	register char last;
	register count, i, j, rdcnt;
	int bufsiz, pid;
	int fd;
	int t_write, t_read, printit;
	int testint(), testurg(), urgent(), report(), die(), timerpt();

	progname = argv[0];

	last = 0xff;
	count = -1;
	itotals = 0.;
	totals = 0.;
	ibytes = 0;
	bytes = 0;
	bufsiz = 512;
	printit = 0;
	fd = -1;

	con.c_mode = CONTCP | CONACT;
	con.c_sbufs = 0;
	con.c_rbufs = 0;
	con.c_timeo = 0;
	con.c_fcon = thishost(thisnet());
	mkanyhost(con.c_lcon);
	con.c_fport = 0;
	con.c_lport = 0;
	wport = 0x1234;
	rport = 0x5678;
	t_write = 1;
	t_read = 1;
	match = 0;
	finis = 0;
	loop = 0;
	eol = 0;
	compare = 0;

	while (argc > 1 && argv[1][0] == '-') {
		switch(argv[1][1]){

		case 'r':               /* read test */
			t_write--;
			t_read++;
			break;

		case 'w':               /* write test */
			t_read--;
			t_write++;
			break;

		case 'd':               /* debug connection */
			con.c_mode |= CONDEBUG;
			break;

		case 'a':               /* await mode */
			con.c_mode &= ~CONACT;
			break;

		case 'h':               /* set foreign host/imp */
			con.c_fcon = gethost(argv[2]);
			argv++; argc--;
			break;

		case 'g':
			con.c_lcon = gethost(argv[2]);
			argv++; argc--;
			break;

		case 'p':               /* set foreign port */
			sscanf(argv[2], "%d", &wport);
			con.c_fport = wport;
			argv++; argc--;
			break;

		case 'q':               /* set local port */
			sscanf(argv[2], "%d", &rport);
			con.c_lport = rport;
			argv++; argc--;
			break;

		case 'x':               /* print after each read/write */
			printit++;
			break;

		case 'b':               /* read/write buffer size */
			sscanf(argv[2], "%D", &bufsiz);
			if (bufsiz > 1024)
				ecmderr(0, "buffer size > 1024\n");
			argv++; argc--;
			break;

		case 'c':               /* send/rcv buffer allocation */
			sscanf(argv[2], "%d", &host);
			con.c_sbufs = host;
			con.c_rbufs = host;
			argv++; argc--;
			break;

		case 't':               /* open timeout */
			sscanf(argv[2], "%d", &host);
			con.c_timeo = host;
			argv++; argc--;
			break;

		case 'l':               /* looping test */
			loop++;
			break;

		case 'm':               /* match read/write size mismatch */
			match++;
			break;

		case 'e':               /* send eols */
			eol++;
			break;

		case 'z':               /* comparison test */
			compare++;
			break;

		case 'i':		/* report every n seconds */
			timer = 30;
			if (argc > 1) {
				timer = atoi(argv[2]);
				argv++; argc--;
			}
			break;

		case 'f':               /* output file */
			if (argc > 1) {
				if ((fd = creat(argv[2], 0666)) < 0)
					ecmderr(errno, "Cannot create %s.\n",
						argv[2]);
				argv++; argc--;
			} else
				printf("No output file name given.\n");
			break;

		case '?':
			goto doc;

		default:
			printf("usage: %s [-rwadelmxz?] [-g <netaddr>] [-h <netaddr>] [-p <fport>] [-q <lport>]\n", 
				argv[0]);
			printf("\t\t[-b <bufsiz>] [-c <conbufs>] [-t <timeout>] [<count>] [-i <intvl>]\n");
			return;
		}
		argv++; argc--;
	}

	if (argc > 1) {
		if (argv[1][0] == '?') {
doc:			printf("TCPTEST OPTIONS:\nopt\tdescription\t\tdefault\n");
			printf("a\tawait mode\t\toff\n");
			printf("b\tset buffer size\t\t512\n");
			printf("c\tset buffer alloc\t1\n");
			printf("d\tdebug mode\t\toff\n");
			printf("e\teol mode\t\toff\n");
			printf("f\tcreate output file\tnull\n");
			printf("g\tset local host\t\tlocal\n");
			printf("h\tset foreign host\tlocal\n");
			printf("i\treport every n secs\t30\n");
			printf("l\tloopback mode\t\toff\n");
			printf("m\trept r/w len mismatch\tno\n");
			printf("p\tset foreign port\t0\n");
			printf("q\tset local port\t\t0\n");
			printf("r\tread test\t\ton\n");
			printf("t\tset open timeout\t30\n");
			printf("w\twrite test\t\ton\n");
			printf("x\tprint after r/w\t\toff\n");
			printf("z\tcompare buffers\t\toff\n");
			return;
		}
		count = atoi(argv[1]);
	}

	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		signal(SIGINT, testint);       
	signal(SIGQUIT, report);           
	signal(SIGURG, urgent);
	signal(SIGTERM, testurg);
	signal(SIGHUP, die);
	signal(SIGALRM, timerpt);

	for (i=0, j=0; i < bufsiz; i++)
		outbuf[i] = j++;

	if (t_read && !t_write)
		goto readit;

	if (t_read && t_write)
		switch (pid = fork()) {

		case -1:
			ecmderr(errno, "cannot fork.\n");

		default:
			break;

readit:		case 0:
			dir = "read";
			if (loop) {
               		       con.c_lport = rport;
               		       con.c_fport = wport;
				con.c_mode &= ~CONACT;
			}
        		if ((fr = open("/dev/net/anyhost", &con)) < 0) 
        			ecmderr(errno, "read open error.\n");
			if (timer > 0)
				alarm(timer);

			if (count >= 0)
        			rdcnt = count * bufsiz;
			else
				rdcnt = 1;

			while (rdcnt > 0 && !finis) {

				if (fd >= 0)
        				for (i=0; i < bufsiz; i++)
        					inbuf[i] = 0;

				ftime(&stime);
				if ((i = read(fr, inbuf, bufsiz)) < 0) {
					if (errno == 35) {
        					ioctl(fr, NETGETS, &outstat);
						printf("read status: %o\n",
							outstat.n_state);
					} else if (errno != EINTR) {
						cmderr(errno, "read error.\n");
        					finis++;
					}

				} else if (i > 0) {
        				ftime(&ttime);
					if (i != bufsiz && match) 
					        printf("read %d: length mismatch -- asked %d got %d\n",
						 count, bufsiz, i);
					else
					        if (printit)
						        printf("read %d: %d\n",
							  count,i);

					if (compare) 
						for (j=0; j < i; j++)
							if (inbuf[j] != ++last) {
								printf("read %d: comparison test failed at position %d char %x last %x\n",
								  count, j, inbuf[j], last);
								last = inbuf[j];
								break;
							}

					if (fd >= 0)
						if (write(fd, inbuf, i) < 0)
							cmderr(errno, "Error writing output file.\n");
					totals += (float)(ttime.time - stime.time) +
						  (float)(ttime.millitm - stime.millitm) / 1000.;
					itotals += (float)(ttime.time - stime.time) +
						  (float)(ttime.millitm - stime.millitm) / 1000.;
					ibytes += i;
        				bytes += i;
					if (count-- >= 0)
        					rdcnt -= i;
				} else {
					printf("read: got EOF\n");
					finis++;
				}

			}
			close(fr);
			dorept(dir, totals, bytes, FALSE);
		        exit(0);
		}

	if (t_write) {

		dir = "write";
		if (loop) {
        		con.c_lport = wport;
        		con.c_fport = rport;
			sleep(1);
		}
		if ((fw = open("/dev/net/anyhost", &con)) < 0)  
			ecmderr(errno, "write open error.\n");
		if (timer > 0)
			alarm(timer);

		if (eol)
			ioctl(fw, NETSETE, 0);

		while (!finis && count != 0) {

			ftime(&stime);
			if ((i = write(fw, outbuf, bufsiz)) < 0) {
				if (errno == 35) {
					ioctl(fw, NETGETS, &outstat);
					printf("write status: %o\n",
						outstat.n_state);
					continue;
				} else if (errno != EINTR) {
					cmderr(errno, "write error.\n");
					finis++;
				}

			} else {
        			ftime(&ttime);
				if (i != bufsiz && match)
				        printf("write %d: length mismatch -- tried %d wrote %d\n",
     					     count, bufsiz, i);
        			else  
        				if (printit)
        					printf("write %d: %d\n", count, i);
				totals += (float)(ttime.time - stime.time) +
					  (float)(ttime.millitm - stime.millitm) / 1000.;
				itotals += (float)(ttime.time - stime.time) +
					  (float)(ttime.millitm - stime.millitm) / 1000.;
        			ibytes += i;
        			bytes += i;
			}

			if (count > 0 && --count <= 0)
				finis++;

		}
		close(fw);
		printf("write done.\n");

		if (t_read)
			wait(0);
		dorept(dir, totals, bytes, FALSE);
	}
}

testint()
{
	printf("Interrupt...\n");
	finis++;
}

testurg()
{
	signal(SIGTERM, testurg);
	printf("Urgent test...\n");
	ioctl(fw, NETSETU, 0);
}

urgent()
{
	signal(SIGURG, urgent);
	printf("Received urgent data\n.");
}

report()
{
	signal(SIGQUIT, report);
	dorept(dir, totals, bytes, FALSE);
}

dorept(title, totals, bytes, brief)
char *title;
float totals;	
int bytes, brief;
{
	long thru;

	printf("%s: ", title);
	if (!brief)
		printf("%D bytes in %6.3f seconds", bytes, totals); 
	if (totals == 0.0)
		putchar('\n');
	else {
		thru = (bytes/totals)*8;
		printf(" %D bits/sec\n", thru);
	}
}

timerpt()
{
	static char title[24];

	signal(SIGALRM, timerpt);
	if (timer > 0)
		alarm(timer);
	sprintf(title, "int %s", dir);
	dorept(title, itotals, ibytes, TRUE);
	sprintf(title, "avg %s", dir);
	dorept(title, totals, bytes, TRUE);
	itotals = 0;
	ibytes = 0;
}

die()
{
	finis++;
}