xref: /original-bsd/sys/tests/netiso/tisrc.c (revision 30928eff)
1 /*-
2  * Copyright (c) 1988, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)tisrc.c	7.8 (Berkeley) 02/25/93";
16 #endif /* not lint */
17 
18 /*
19  * This is a test program to be a source for ISO transport.
20  */
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/uio.h>
24 #include <sys/ioctl.h>
25 #include <net/route.h>
26 #include <net/if.h>
27 #define  TCPT_NTIMERS 4
28 #include <netiso/iso.h>
29 #include <netiso/tp_user.h>
30 
31 #include <stdio.h>
32 #include <errno.h>
33 #include <ctype.h>
34 #include <netdb.h>
35 
36 
37 #define dbprintf if(verbose)printf
38 #ifdef __STDC__
39 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
40 		if (x<0) {perror(#a); exit(1);}}
41 #else
42 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
43 		if (x<0) {perror("a");exit(1);}}
44 #endif
45 
46 struct	iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/};
47 struct	iso_addr *iso_addr();
48 struct  sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s;
49 struct  sockaddr_iso from_s = { sizeof(from_s), AF_ISO }, *from = 0;
50 struct  sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s;
51 struct	tp_conn_param tp_params;
52 fd_set	readfds, writefds, exceptfds;
53 long size, count = 0;
54 int verbose = 1, selectp, socktype = SOCK_SEQPACKET, nobuffs, errno, playtag = 0;
55 int echop = 0, dgramp = 0, debug = 0, tp0mode = 0, dumpnodata  = 0, tuba = 0;
56 short portnumber = 3000;
57 char your_it[] = "You're it!";
58 char *Servername, *conndata, data_msg[8192];
59 char Serverbuf[128];
60 char name[128];
61 struct iovec iov[1] = {data_msg};
62 union {
63     struct {
64 	    struct cmsghdr	cmhdr;
65 	    char		cmdata[128 - sizeof(struct cmsghdr)];
66     } cm;
67     char data[128];
68 } cm;
69 struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
70 
71 main(argc, argv)
72 int argc;
73 char *argv[];
74 {
75 	register char **av = argv;
76 	register char *cp;
77 	u_long len;
78 	int handy;
79 
80 	while(--argc > 0) {
81 		av++;
82 		if(strcmp(*av,"Servername")==0) {
83 			av++;
84 			Servername = *av;
85 			argc--;
86 		} else if(strcmp(*av,"conndata")==0) {
87 			av++;
88 			conndata = *av;
89 			argc--;
90 		} else if(strcmp(*av,"host")==0) {
91 			av++;
92 			to_s.siso_addr = *iso_addr(*av);
93 			argc--;
94 		} else if(strcmp(*av,"from")==0) {
95 			av++;
96 			from_s.siso_addr = *iso_addr(*av);
97 			from = &from_s;
98 			argc--;
99 		} else if(strcmp(*av,"port")==0) {
100 			av++;
101 			sscanf(*av,"%hd",&portnumber);
102 			argc--;
103 		} else if(strcmp(*av,"count")==0) {
104 			av++;
105 			sscanf(*av,"%ld",&count);
106 			argc--;
107 		} else if(strcmp(*av,"size")==0) {
108 			av++;
109 			sscanf(*av,"%ld",&size);
110 			iov->iov_len = size;
111 		} else if(strcmp(*av,"stream")==0) {
112 			socktype = SOCK_STREAM;
113 		} else if (strcmp(*av, "echo")==0) {
114 			echop++;
115 		} else if (strcmp(*av,"eon") == 0) {
116 			unsigned long l, inet_addr();
117 
118 			l = inet_addr(*++av); argc--;
119 			to_s.siso_addr = eon;
120 			bcopy((char *)&l, &to_s.siso_data[15], 4);
121 		}
122 	}
123 	maketoaddr();
124 	tisrc();
125 }
126 
127 maketoaddr()
128 {
129 	if (Servername) {
130 		int tlen = strlen(Servername);
131 		int len =  tlen + TSEL(to) - (caddr_t) to;
132 		if (len < sizeof(*to)) len = sizeof(*to);
133 		if (len > to->siso_len) {
134 			old = to;
135 			to = (struct sockaddr_iso *)malloc(len);
136 			*to = *old; /* We dont care if all old tsel is copied*/
137 			if (old != &to_s) free(old);
138 		}
139 		bcopy(Servername, TSEL(to), tlen);
140 		to->siso_tlen = tlen;
141 	} else {
142 		to->siso_tlen = sizeof(portnumber);
143 		portnumber = htons(portnumber);
144 		bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber));
145 	}
146 }
147 
148 tisrc() {
149 	int x, s, pid, on = 1, flags = 8, n;
150 	int proto = (tp0mode ? ISOPROTO_TP0 : (tuba ? ISOPROTO_TCP : 0 ));
151 	int socktype = (dgramp ? SOCK_DGRAM :
152 			(tuba ? SOCK_STREAM :SOCK_SEQPACKET));
153 
154 	try(socket, (AF_ISO, socktype, proto),"");
155 	s = x;
156 
157 	if (debug)
158 		try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), "");
159 	if (dgramp == 0) {
160 		if (conndata)
161 			doconndata(s);
162 		if (from) {
163 			try(bind,
164 			    (s, (struct sockaddr *)from, from->siso_len), "");
165 		}
166 		try(connect, (s, (struct sockaddr *) to, to->siso_len), "");
167 		recv_cdata(s);
168 	}
169 	if (selectp) {
170 		FD_ZERO(&writefds); FD_SET(s, &writefds);
171 		select(1, &writefds, 0, 0, 0);
172 	}
173 	do {
174 		if (size <= 0 && get_record(&flags) == EOF)
175 			exit(0);
176 		n = put_record(s, flags);
177 		if (n < iov->iov_len) {
178 			if (n == -1 && errno == 55) {
179 				nobuffs++;
180 				if (count) ++count;
181 				continue;
182 			}
183 			fprintf(stderr, "wrote %d < %d, count %d,",
184 						n, iov->iov_len, count);
185 			perror("due to");
186 		}
187 	} while (count == 0 || --count >= 1);
188 	if (playtag) {
189 		printf("Tag time!\n");
190 		iov->iov_base = your_it;
191 		iov->iov_len = sizeof your_it;
192 		sendmsg(s, &msg, MSG_EOR);
193 		sendmsg(s, &msg, MSG_EOR);
194 		iov->iov_base = data_msg;
195 		iov->iov_len = sizeof data_msg;
196 		try(recvmsg, (s, &msg, flags), " playtag ");
197 	}
198 	if(nobuffs) {
199 		printf("looped %d times waiting for bufs\n", nobuffs);
200 	}
201 }
202 
203 recv_cdata(s)
204 int s;
205 {
206 	int x;
207 	iov->iov_len = 0;
208 	msg.msg_controllen = sizeof(cm);
209 	msg.msg_control = (char *)&cm;
210 	try(recvmsg,(s, &msg, 0), "confirm data?");
211 	if (msg.msg_controllen)
212 		dumpit("", (u_short *)&cm, msg.msg_controllen);
213 	msg.msg_control = 0;
214 	msg.msg_controllen = 0;
215 }
216 
217 int localsize;
218 char dupbuf[4096];
219 
220 struct savebuf {
221 	struct savebuf *s_next;
222 	struct savebuf *s_prev;
223 	int	s_n;
224 	int	s_flags;
225 } savebuf = {&savebuf, &savebuf};
226 
227 void
228 savedata(n, flags)
229 int n;
230 {
231 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
232 	if (s == 0)
233 		return;
234 	insque(s, savebuf.s_prev);
235 	s->s_n = n;
236 	s->s_flags = flags;
237 	bcopy(iov->iov_base, (char *)(s + 1), n);
238 }
239 
240 checkback(fd)
241 int fd;
242 {
243 	int n, nn;
244 	register struct savebuf *s = savebuf.s_next, *t;
245 	register char *cp = data_msg;
246 	while (s != &savebuf) {
247 		nn = s->s_n;
248 		do {
249 			msg.msg_flags = 0;
250 			iov->iov_len = nn;
251 			iov->iov_base = cp;
252 			n = recvmsg(fd, &msg, 0);
253 			cp += n;
254 			nn -= n;
255 		} while (dgramp == 0 && nn > 0 && !(msg.msg_flags & MSG_EOR));
256 		iov->iov_base = data_msg;
257 		if (dgramp) {
258 			if (msg.msg_namelen)
259 				dumpit("from: ", to, msg.msg_namelen);
260 			msg.msg_namelen = old->siso_len;
261 		}
262 		n = s->s_n - nn;
263 		dbprintf("echoed %d", n);
264 		if (nn)
265 			dbprintf(" instead of %d", s->s_n);
266 		if (bcmp((char *)(s + 1), data_msg, n))
267 			dbprintf(", with mismatched data");
268 		if (nn && (msg.msg_flags & MSG_EOR))
269 			dbprintf(" and with %d unchecked after EOR", nn);
270 		dbprintf("\n");
271 		t = s; s = s->s_next; remque(t); free((char *)t);
272 	}
273 }
274 
275 
276 put_record(s, flags)
277 int s, flags;
278 {
279 	char *buf;
280 	int x, saved_x;
281 
282 	msg.msg_flags = flags;
283 	if (verbose) {
284 		if (msg.msg_controllen) {
285 			printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
286 			dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen);
287 		}
288 		if (iov->iov_len) {
289 			printf("sending: %s %s",
290 			(flags & MSG_OOB ? "(OOB Data)" : ""),
291 				(flags & MSG_EOR ? "(Record Mark)" : ""));
292 			dumpit("data: ", data_msg, localsize);
293 		}
294 	}
295 	if (echop)
296 		savedata(iov->iov_len, flags);
297 	if (dgramp) {
298 		msg.msg_name = (caddr_t)to;
299 		msg.msg_namelen = to->siso_len;
300 	}
301 	try(sendmsg, (s, &msg, flags), " put_record ");
302 	saved_x = x;
303 	if (echop && (flags & MSG_EOR))
304 		checkback(s);
305 	bcopy(old, to, old->siso_len);
306 	msg.msg_control = 0;
307 	return (saved_x);
308 }
309 dumpit(what, where, n)
310 char *what; unsigned short *where; int n;
311 {
312 	unsigned short *s = where;
313 	unsigned short *z = where + (n+1)/2;
314 	int count = 0;
315 	if (dumpnodata)
316 		return;
317 	printf(what);
318 	while(s < z) {
319 		count++;
320 		printf("%x ",*s++);
321 		if ((count & 15) == 0)
322 			putchar('\n');
323 	}
324 	if (count & 15)
325 		putchar('\n');
326 	fflush(stdout);
327 }
328 int *datasize = &iov->iov_len;
329 char *cp, *cplim;
330 
331 get_control_data(type)
332 {
333 
334 	datasize = (int *)&msg.msg_controllen;
335 	cp = cm.cm.cmdata;
336 	cplim = cp + sizeof(cm.cm.cmdata);
337 	cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT;
338 	cm.cm.cmhdr.cmsg_type = type;
339 	msg.msg_control = cm.data;
340 }
341 
342 doconndata(s)
343 {
344 	get_control_data(TPOPT_CONN_DATA);
345 	*datasize = strlen(conndata) + sizeof(cm.cm.cmhdr);
346 	cm.cm.cmhdr.cmsg_len = *datasize;
347 	bcopy(conndata, cp, *datasize);
348 	put_record(s, 0);
349 }
350 
351 get_altbuf(addrbuf)
352 char *addrbuf;
353 {
354 	if (dgramp == 0) {
355 		printf("illegal option for stream\n");
356 		return 1;
357 	}
358 	return (scanf("%s", addrbuf) == EOF ? 1 : 0);
359 }
360 
361 get_record(flags)
362 int *flags;
363 {
364 	int factor = 1, x = 0, newaddr = 0;
365 	static repeatcount, repeatsize;
366 	char workbuf[10240];
367 	char addrbuf[128];
368 
369 	if (repeatcount > 0) {
370 		repeatcount--;
371 		return;
372 	}
373 
374 	*flags = 0;
375 	*datasize = 0;
376 	datasize = &iov->iov_len;
377 	cp = data_msg;
378 	cplim  = cp + sizeof(data_msg);
379 
380 	for(;;) {
381 		x = scanf("%s", workbuf);
382 		if (x == EOF)
383 			break;
384 		if (strcmp(workbuf, "host") == 0) {
385 			if (get_altbuf(addrbuf))
386 				break;
387 			to->siso_addr = *iso_addr(addrbuf);
388 			newaddr = 1;
389 		} else if (strcmp(workbuf, "Servername") == 0) {
390 			if (get_altbuf(Serverbuf))
391 				break;
392 			Servername = Serverbuf;
393 			newaddr = 1;
394 		} else if (strcmp(workbuf, "port") == 0) {
395 			x = scanf("%hd", &portnumber);
396 			if (x == EOF)
397 				break;
398 			Servername = 0;
399 			newaddr = 1;
400 		} else if (strcmp(workbuf, "repeat") == 0) {
401 			x = scanf("%d", &repeatcount);
402 			if (repeatcount <= 0) repeatcount = 1;
403 			repeatcount--;
404 			if (x == EOF)
405 				break;
406 		} else if (strcmp(workbuf, "disc") == 0)
407 			x = get_control_data(TPOPT_DISC_DATA);
408 		else if (strcmp(workbuf, "cfrm") == 0)
409 			x = get_control_data(TPOPT_CFRM_DATA);
410 		else if (strcmp(workbuf, "oob") == 0)
411 			*flags |= MSG_OOB;
412 		else if (strcmp(workbuf, "eom") == 0)
413 			*flags |= MSG_EOR;
414 		else if (strcmp(workbuf, "factor") == 0) {
415 			x = scanf("%d", &factor);
416 			if (factor <= 0) factor = 1;
417 			if (x == EOF)
418 				break;
419 		} else {
420 			int len = strlen(workbuf);
421 			localsize = 0;
422 			while ((factor-- > 0) &&
423 			       ((cp + len) < cplim)) {
424 					strcpy(cp, workbuf);
425 					cp += len;
426 					localsize += len;
427 			}
428 			*datasize = localsize;
429 			if (datasize != &iov->iov_len) {
430 				*datasize += sizeof(cm.cm.cmhdr);
431 				repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
432 			}
433 			break;
434 		}
435 	}
436 	errno = 0;
437 	if (newaddr)
438 		maketoaddr();
439 	return (x);
440 }
441