207 lines · 3.3 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <ctype.h> int	debug;long	errrate;long	droprate;int	framing;int	nocompress;int	noipcompress;char	*ppp = "8.out";char	*mtu; voidpppopen(int fd, char *net, char *local, char *remote){	char *argv[16];	int argc; 	switch(fork()){	case -1:		fprint(2, "testppp: can't fork: %r\n");		exits(0);	case 0:		return;	default:		break;	} 	dup(fd, 0);	dup(fd, 1); 	argc = 0;	argv[argc++] = ppp;	if(debug)		argv[argc++] = "-d";	if(framing)		argv[argc++] = "-f";	if(nocompress)		argv[argc++] = "-c";	if(noipcompress)		argv[argc++] = "-C";	if(mtu){		argv[argc++] = "-m";		argv[argc++] = mtu;	}	argv[argc++] = "-x";	argv[argc++] = net;	if(local){		argv[argc++] = local;		if(remote)			argv[argc++] = remote;	}	argv[argc] = 0;	exec(ppp, argv);} voidprintbuf(uchar *p, int n){	int i;	uchar *e;	char buf[32*5]; 	if(n > 32)		n = 32;		i = 0;	for(e = p + n; p < e; p++){		if(isprint(*p))			i += sprint(buf+i, "%c ", *p);		else			i += sprint(buf+i, "%2.2ux ", *p);	}	fprint(2, "%s\n", buf);} voidxfer(int from, int to){	uchar buf[4096];	int i, n, modified, ok, total, errs, dropped; 	if(fork() == 0)		return; 	total = ok = errs = dropped = 0;	for(;;){		n = read(from, buf, sizeof(buf));		if(n <= 0){			fprint(2, "%d -> %d EOF\n", from, to);			exits(0);		}		modified = 0;		if(errrate){			for(i = 0; i < n; i++){				if(lnrand(errrate) == 0){					buf[i] ^= 0xff;					modified = 1;				}			}		}		if(droprate && lnrand(droprate) == 0){			fprint(2, "!!!!!!!!!!!!!!%d -> %d dropped %d (%d/%d)\n", from, to, ok, dropped, total);			ok = 0;			dropped++;			total++;			continue;		}		if(modified){			fprint(2, "!!!!!!!!!!!!!!%d -> %d %d (%d/%d)\n", from, to, ok, errs, total);			ok = 0;			errs++;		} else			ok++;		total++;		if(debug > 1){			fprint(2, "%d -> %d (%d)", from, to, n);			printbuf(buf, n);		}		n = write(to, buf, n);		if(n < 0){			fprint(2, "%d -> %d write err\n", from, to);			exits(0);		}	}} voidusage(void){	fprint(2, "usage: testppp [-cCDf] [-e errrate] [-d droprate] [-m mtu] [-p ppp]\n");	exits("usage");} voidmain(int argc, char **argv){	char *s;	int pfd1[2];	int pfd2[2]; 	errrate = 0;	droprate = 0;	ARGBEGIN{	case 'c':		nocompress = 1;		break;	case 'C':		noipcompress = 1;		break;	case 'd':		s = ARGF();		if(s)			droprate = strtol(s, nil, 0);		break;	case 'D':		debug++;		break;	case 'e':		s = ARGF();		if(s)			errrate = strtol(s, nil, 0);		break;	case 'f':		framing = 1;		break;	case 'm':		mtu = ARGF();		break;	case 'p':		ppp = ARGF();		if(ppp == nil)			usage();		break;	default:		usage();		break;	}ARGEND	if(argc)		usage(); 	pipe(pfd1);	pipe(pfd2); 	bind("#I2", "/net.alt2", MCREATE);	bind("#I1", "/net.alt", MCREATE);	pppopen(pfd1[0], "/net.alt2", "135.104.99.1", "135.104.99.2");	pppopen(pfd2[0], "/net.alt", 0, 0); 	close(pfd1[0]);	close(pfd2[0]); 	xfer(pfd1[1], pfd2[1]);	xfer(pfd2[1], pfd1[1]);	exits(0);}