xref: /plan9-contrib/sys/src/cmd/ip/ppp/testppp.c (revision 6b6b9ac8b0b103b1e30e4d019522a78c950fce74)
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 
5 int	debug;
6 long	errrate;
7 long	droprate;
8 int	framing;
9 int	nocompress;
10 int	noipcompress;
11 char	*ppp = "8.out";
12 char	*mtu;
13 
14 void
pppopen(int fd,char * net,char * local,char * remote)15 pppopen(int fd, char *net, char *local, char *remote)
16 {
17 	char *argv[16];
18 	int argc;
19 
20 	switch(fork()){
21 	case -1:
22 		fprint(2, "testppp: can't fork: %r\n");
23 		exits(0);
24 	case 0:
25 		return;
26 	default:
27 		break;
28 	}
29 
30 	dup(fd, 0);
31 	dup(fd, 1);
32 
33 	argc = 0;
34 	argv[argc++] = ppp;
35 	if(debug)
36 		argv[argc++] = "-d";
37 	if(framing)
38 		argv[argc++] = "-f";
39 	if(nocompress)
40 		argv[argc++] = "-c";
41 	if(noipcompress)
42 		argv[argc++] = "-C";
43 	if(mtu){
44 		argv[argc++] = "-m";
45 		argv[argc++] = mtu;
46 	}
47 	argv[argc++] = "-x";
48 	argv[argc++] = net;
49 	if(local){
50 		argv[argc++] = local;
51 		if(remote)
52 			argv[argc++] = remote;
53 	}
54 	argv[argc] = 0;
55 	exec(ppp, argv);
56 }
57 
58 void
printbuf(uchar * p,int n)59 printbuf(uchar *p, int n)
60 {
61 	int i;
62 	uchar *e;
63 	char buf[32*5];
64 
65 	if(n > 32)
66 		n = 32;
67 
68 	i = 0;
69 	for(e = p + n; p < e; p++){
70 		if(isprint(*p))
71 			i += sprint(buf+i, "%c ", *p);
72 		else
73 			i += sprint(buf+i, "%2.2ux ", *p);
74 	}
75 	fprint(2, "%s\n", buf);
76 }
77 
78 void
xfer(int from,int to)79 xfer(int from, int to)
80 {
81 	uchar buf[4096];
82 	int i, n, modified, ok, total, errs, dropped;
83 
84 	if(fork() == 0)
85 		return;
86 
87 	total = ok = errs = dropped = 0;
88 	for(;;){
89 		n = read(from, buf, sizeof(buf));
90 		if(n <= 0){
91 			fprint(2, "%d -> %d EOF\n", from, to);
92 			exits(0);
93 		}
94 		modified = 0;
95 		if(errrate){
96 			for(i = 0; i < n; i++){
97 				if(lnrand(errrate) == 0){
98 					buf[i] ^= 0xff;
99 					modified = 1;
100 				}
101 			}
102 		}
103 		if(droprate && lnrand(droprate) == 0){
104 			fprint(2, "!!!!!!!!!!!!!!%d -> %d dropped %d (%d/%d)\n", from, to, ok, dropped, total);
105 			ok = 0;
106 			dropped++;
107 			total++;
108 			continue;
109 		}
110 		if(modified){
111 			fprint(2, "!!!!!!!!!!!!!!%d -> %d %d (%d/%d)\n", from, to, ok, errs, total);
112 			ok = 0;
113 			errs++;
114 		} else
115 			ok++;
116 		total++;
117 		if(debug > 1){
118 			fprint(2, "%d -> %d (%d)", from, to, n);
119 			printbuf(buf, n);
120 		}
121 		n = write(to, buf, n);
122 		if(n < 0){
123 			fprint(2, "%d -> %d write err\n", from, to);
124 			exits(0);
125 		}
126 	}
127 }
128 
129 void
usage(void)130 usage(void)
131 {
132 	fprint(2, "usage: testppp [-cCDf] [-e errrate] [-d droprate] [-m mtu] [-p ppp]\n");
133 	exits("usage");
134 }
135 
136 void
main(int argc,char ** argv)137 main(int argc, char **argv)
138 {
139 	char *s;
140 	int pfd1[2];
141 	int pfd2[2];
142 
143 	errrate = 0;
144 	droprate = 0;
145 	ARGBEGIN{
146 	case 'c':
147 		nocompress = 1;
148 		break;
149 	case 'C':
150 		noipcompress = 1;
151 		break;
152 	case 'd':
153 		s = ARGF();
154 		if(s)
155 			droprate = strtol(s, nil, 0);
156 		break;
157 	case 'D':
158 		debug++;
159 		break;
160 	case 'e':
161 		s = ARGF();
162 		if(s)
163 			errrate = strtol(s, nil, 0);
164 		break;
165 	case 'f':
166 		framing = 1;
167 		break;
168 	case 'm':
169 		mtu = ARGF();
170 		break;
171 	case 'p':
172 		ppp = ARGF();
173 		if(ppp == nil)
174 			usage();
175 		break;
176 	default:
177 		usage();
178 		break;
179 	}ARGEND
180 	if(argc)
181 		usage();
182 
183 	pipe(pfd1);
184 	pipe(pfd2);
185 
186 	bind("#I2", "/net.alt2", MCREATE);
187 	bind("#I1", "/net.alt", MCREATE);
188 	pppopen(pfd1[0], "/net.alt2", "135.104.99.1", "135.104.99.2");
189 	pppopen(pfd2[0], "/net.alt", 0, 0);
190 
191 	close(pfd1[0]);
192 	close(pfd2[0]);
193 
194 	xfer(pfd1[1], pfd2[1]);
195 	xfer(pfd2[1], pfd1[1]);
196 	exits(0);
197 }
198 
199