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