xref: /csrg-svn/sys/tests/netiso/tisrc.c (revision 50891)
149352Sbostic /*-
249352Sbostic  * Copyright (c) 1988, 1990 The Regents of the University of California.
344323Ssklower  * All rights reserved.
444323Ssklower  *
544323Ssklower  * %sccs.include.redist.c%
644323Ssklower  */
749352Sbostic 
844323Ssklower #ifndef lint
949352Sbostic char copyright[] =
1049352Sbostic "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
1149352Sbostic  All rights reserved.\n";
1244323Ssklower #endif /* not lint */
1344323Ssklower 
1449352Sbostic #ifndef lint
15*50891Ssklower static char sccsid[] = "@(#)tisrc.c	7.6 (Berkeley) 08/22/91";
1649352Sbostic #endif /* not lint */
1749352Sbostic 
1844323Ssklower /*
1948713Ssklower  * This is a test program to be a source for ISO transport.
2044323Ssklower  */
2144323Ssklower #include <sys/types.h>
2244323Ssklower #include <sys/socket.h>
2344323Ssklower #include <sys/uio.h>
2444323Ssklower #include <sys/ioctl.h>
2544323Ssklower #include <net/route.h>
2644323Ssklower #include <net/if.h>
2744323Ssklower #define  TCPT_NTIMERS 4
2844323Ssklower #include <netiso/iso.h>
2944323Ssklower #include <netiso/tp_user.h>
3044323Ssklower 
3144323Ssklower #include <stdio.h>
3244323Ssklower #include <errno.h>
3344323Ssklower #include <ctype.h>
3444323Ssklower #include <netdb.h>
3544323Ssklower 
3644323Ssklower 
3744323Ssklower #define dbprintf if(verbose)printf
38*50891Ssklower #ifdef __STDC__
39*50891Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
40*50891Ssklower 		if (x<0) {perror(#a); exit(1);}}
41*50891Ssklower #else
42*50891Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
43*50891Ssklower 		if (x<0) {perror("a");exit(1);}}
44*50891Ssklower #endif
4544323Ssklower 
4644323Ssklower struct	iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/};
4749065Ssklower struct	iso_addr *iso_addr();
4844323Ssklower struct  sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s;
4948713Ssklower struct  sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s;
5048843Ssklower struct	tp_conn_param tp_params;
5144323Ssklower fd_set	readfds, writefds, exceptfds;
52*50891Ssklower long size, count = 0;
5344323Ssklower int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0;
54*50891Ssklower int echop = 0, dgramp = 0, debug = 0, tp0mode = 0, dumpnodata  = 0;
5544323Ssklower short portnumber = 3000;
5644323Ssklower char your_it[] = "You're it!";
57*50891Ssklower char *Servername, *conndata, data_msg[8192];
5848713Ssklower char Serverbuf[128];
5948713Ssklower char name[128];
6044323Ssklower struct iovec iov[1] = {data_msg};
6144323Ssklower union {
6244323Ssklower     struct {
6344323Ssklower 	    struct cmsghdr	cmhdr;
6448713Ssklower 	    char		cmdata[128 - sizeof(struct cmsghdr)];
6544323Ssklower     } cm;
6644323Ssklower     char data[128];
6744323Ssklower } cm;
6844323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
6944323Ssklower 
7044323Ssklower main(argc, argv)
7144323Ssklower int argc;
7244323Ssklower char *argv[];
7344323Ssklower {
7444323Ssklower 	register char **av = argv;
7544323Ssklower 	register char *cp;
7644323Ssklower 	u_long len;
7744323Ssklower 	int handy;
7844323Ssklower 
7944323Ssklower 	while(--argc > 0) {
8044323Ssklower 		av++;
8144323Ssklower 		if(strcmp(*av,"Servername")==0) {
8244323Ssklower 			av++;
8348713Ssklower 			Servername = *av;
8444323Ssklower 			argc--;
8544323Ssklower 		} else if(strcmp(*av,"conndata")==0) {
8644323Ssklower 			av++;
8744323Ssklower 			conndata = *av;
8844323Ssklower 			argc--;
8944323Ssklower 		} else if(strcmp(*av,"host")==0) {
9044323Ssklower 			av++;
9148713Ssklower 			to_s.siso_addr = *iso_addr(*av);
9244323Ssklower 			argc--;
9344323Ssklower 		} else if(strcmp(*av,"port")==0) {
9444323Ssklower 			av++;
9544323Ssklower 			sscanf(*av,"%hd",&portnumber);
9644323Ssklower 			argc--;
9744323Ssklower 		} else if(strcmp(*av,"count")==0) {
9844323Ssklower 			av++;
9944323Ssklower 			sscanf(*av,"%ld",&count);
10044323Ssklower 			argc--;
10144323Ssklower 		} else if(strcmp(*av,"size")==0) {
10244323Ssklower 			av++;
10344323Ssklower 			sscanf(*av,"%ld",&size);
10444323Ssklower 			iov->iov_len = size;
10544323Ssklower 		} else if(strcmp(*av,"stream")==0) {
10644323Ssklower 			type = SOCK_STREAM;
107*50891Ssklower 		} else if (strcmp(*av, "echo")==0) {
108*50891Ssklower 			echop++;
10944323Ssklower 		} else if (strcmp(*av,"eon") == 0) {
11044323Ssklower 			unsigned long l, inet_addr();
11144323Ssklower 
11244323Ssklower 			l = inet_addr(*++av); argc--;
11344323Ssklower 			to_s.siso_addr = eon;
11444323Ssklower 			bcopy((char *)&l, &to_s.siso_data[15], 4);
11544323Ssklower 		}
11644323Ssklower 	}
11748713Ssklower 	maketoaddr();
11848713Ssklower 	tisrc();
11948713Ssklower }
12048713Ssklower 
12148713Ssklower maketoaddr()
12248713Ssklower {
12348713Ssklower 	if (Servername) {
12448713Ssklower 		int tlen = strlen(Servername);
12548713Ssklower 		int len =  tlen + TSEL(to) - (caddr_t) to;
12648713Ssklower 		if (len < sizeof(*to)) len = sizeof(*to);
12748713Ssklower 		if (len > to->siso_len) {
12849065Ssklower 			old = to;
12944323Ssklower 			to = (struct sockaddr_iso *)malloc(len);
13049065Ssklower 			*to = *old; /* We dont care if all old tsel is copied*/
13149065Ssklower 			if (old != &to_s) free(old);
13244323Ssklower 		}
13349065Ssklower 		bcopy(Servername, TSEL(to), tlen);
13449065Ssklower 		to->siso_tlen = tlen;
13544323Ssklower 	} else {
13649065Ssklower 		to->siso_tlen = sizeof(portnumber);
13744323Ssklower 		portnumber = htons(portnumber);
13849065Ssklower 		bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber));
13944323Ssklower 	}
14044323Ssklower }
14144323Ssklower 
14244323Ssklower tisrc() {
14348843Ssklower 	int x, s, pid, on = 1, flags = 8, n, proto = tp0mode ? ISOPROTO_TP0: 0;
14444323Ssklower 
14548713Ssklower 	if (dgramp) type = SOCK_DGRAM;
14648843Ssklower 	try(socket, (AF_ISO, type, proto),"");
14744323Ssklower 	s = x;
14844323Ssklower 
14948713Ssklower 	if (debug)
15048713Ssklower 		try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), "");
15148713Ssklower 	if (dgramp == 0) {
15248713Ssklower 		if (conndata)
15348713Ssklower 			doconndata(s);
15448713Ssklower 		try(connect, (s, (struct sockaddr *) to, to->siso_len), "");
155*50891Ssklower 		recv_cdata(s);
15648713Ssklower 	}
15744323Ssklower 	if (selectp) {
15844323Ssklower 		FD_ZERO(&writefds); FD_SET(s, &writefds);
15944323Ssklower 		select(1, &writefds, 0, 0, 0);
16044323Ssklower 	}
161*50891Ssklower 	do {
16244323Ssklower 		if (size <= 0 && get_record(&flags) == EOF)
16344323Ssklower 			exit(0);
16444323Ssklower 		n = put_record(s, flags);
16544323Ssklower 		if (n < iov->iov_len) {
166*50891Ssklower 			if (n == -1 && errno == 55) {
16744323Ssklower 				nobuffs++;
168*50891Ssklower 				if (count) ++count;
16944323Ssklower 				continue;
17044323Ssklower 			}
17144323Ssklower 			fprintf(stderr, "wrote %d < %d, count %d,",
17244323Ssklower 						n, iov->iov_len, count);
17344323Ssklower 			perror("due to");
17444323Ssklower 		}
175*50891Ssklower 	} while (count == 0 || --count >= 1);
17644323Ssklower 	if (playtag) {
17744323Ssklower 		printf("Tag time!\n");
17844323Ssklower 		iov->iov_base = your_it;
17944323Ssklower 		iov->iov_len = sizeof your_it;
18044323Ssklower 		sendmsg(s, &msg, MSG_EOR);
18144323Ssklower 		sendmsg(s, &msg, MSG_EOR);
18244323Ssklower 		iov->iov_base = data_msg;
18344323Ssklower 		iov->iov_len = sizeof data_msg;
18444323Ssklower 		try(recvmsg, (s, &msg, flags), " playtag ");
18544323Ssklower 	}
18644323Ssklower 	if(nobuffs) {
18744323Ssklower 		printf("looped %d times waiting for bufs\n", nobuffs);
18844323Ssklower 	}
18944323Ssklower }
190*50891Ssklower 
191*50891Ssklower recv_cdata(s)
192*50891Ssklower int s;
193*50891Ssklower {
194*50891Ssklower 	int x;
195*50891Ssklower 	iov->iov_len = 0;
196*50891Ssklower 	msg.msg_controllen = sizeof(cm);
197*50891Ssklower 	msg.msg_control = (char *)&cm;
198*50891Ssklower 	try(recvmsg,(s, &msg, 0), "confirm data?");
199*50891Ssklower 	if (msg.msg_controllen)
200*50891Ssklower 		dumpit("", (u_short *)&cm, msg.msg_controllen);
201*50891Ssklower 	msg.msg_control = 0;
202*50891Ssklower 	msg.msg_controllen = 0;
203*50891Ssklower }
204*50891Ssklower 
20544323Ssklower int localsize;
20644323Ssklower char dupbuf[4096];
20744323Ssklower 
208*50891Ssklower struct savebuf {
209*50891Ssklower 	struct savebuf *s_next;
210*50891Ssklower 	struct savebuf *s_prev;
211*50891Ssklower 	int	s_n;
212*50891Ssklower 	int	s_flags;
213*50891Ssklower } savebuf = {&savebuf, &savebuf};
214*50891Ssklower 
215*50891Ssklower void
216*50891Ssklower savedata(n, flags)
217*50891Ssklower int n;
218*50891Ssklower {
219*50891Ssklower 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
220*50891Ssklower 	if (s == 0)
221*50891Ssklower 		return;
222*50891Ssklower 	insque(s, savebuf.s_prev);
223*50891Ssklower 	s->s_n = n;
224*50891Ssklower 	s->s_flags = flags;
225*50891Ssklower 	bcopy(iov->iov_base, (char *)(s + 1), n);
226*50891Ssklower }
227*50891Ssklower 
228*50891Ssklower checkback(s)
229*50891Ssklower int s;
230*50891Ssklower {
231*50891Ssklower 	int n, nn;
232*50891Ssklower 	register struct savebuf *s = savebuf.s_next, *t;
233*50891Ssklower 	register char *cp = data_msg;
234*50891Ssklower 	while (s != &savebuf) {
235*50891Ssklower 		nn = s->s_n;
236*50891Ssklower 		do {
237*50891Ssklower 			msg.msg_flags = 0;
238*50891Ssklower 			iov->iov_len = nn;
239*50891Ssklower 			iov->iov_base = cp;
240*50891Ssklower 			n = recvmsg(s, &msg, s->s_flags);
241*50891Ssklower 			cp += n;
242*50891Ssklower 			nn -= n;
243*50891Ssklower 		} while (dgramp == 0 && nn > 0 && !(msg.msg_flags & MSG_EOR));
244*50891Ssklower 		iov->iov_base = data_msg;
245*50891Ssklower 		if (dgramp) {
246*50891Ssklower 			if (msg.msg_namelen)
247*50891Ssklower 				dumpit("from: ", to, msg.msg_namelen);
248*50891Ssklower 			msg.msg_namelen = old->siso_len;
249*50891Ssklower 		}
250*50891Ssklower 		n = s->s_n - nn;
251*50891Ssklower 		dbprintf("echoed %d", n);
252*50891Ssklower 		if (nn)
253*50891Ssklower 			dbprintf(" instead of %d", s->s_n);
254*50891Ssklower 		if (bcmp((char *)(s + 1), data_msg, n))
255*50891Ssklower 			dbprintf(", with mismatched data");
256*50891Ssklower 		if (nn && (msg.msg_flags & MSG_EOR))
257*50891Ssklower 			dbprintf(" and with %d unchecked after EOR", nn);
258*50891Ssklower 		dbprintf("\n");
259*50891Ssklower 		t = s; s = s->s_next; remque(t); free((char *)t);
260*50891Ssklower 	}
261*50891Ssklower }
262*50891Ssklower 
263*50891Ssklower 
26444323Ssklower put_record(s, flags)
26544323Ssklower int s, flags;
26644323Ssklower {
26744323Ssklower 	char *buf;
26844323Ssklower 	int x, saved_x;
26944323Ssklower 
27044323Ssklower 	msg.msg_flags = flags;
27144323Ssklower 	if (verbose) {
27244323Ssklower 		if (msg.msg_controllen) {
27344323Ssklower 			printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
27448713Ssklower 			dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen);
27544323Ssklower 		}
27644323Ssklower 		if (iov->iov_len) {
27744323Ssklower 			printf("sending: %s %s",
27844323Ssklower 			(flags & MSG_OOB ? "(OOB Data)" : ""),
27944323Ssklower 				(flags & MSG_EOR ? "(Record Mark)" : ""));
28048713Ssklower 			dumpit("data: ", data_msg, localsize);
28144323Ssklower 		}
28244323Ssklower 	}
283*50891Ssklower 	if (echop)
284*50891Ssklower 		savedata(iov->iov_len, flags);
28548713Ssklower 	if (dgramp) {
28648713Ssklower 		msg.msg_name = (caddr_t)to;
28748713Ssklower 		msg.msg_namelen = to->siso_len;
28848713Ssklower 	}
28944323Ssklower 	try(sendmsg, (s, &msg, flags), " put_record ");
29044323Ssklower 	saved_x = x;
291*50891Ssklower 	if (echop && (flags & MSG_EOR))
292*50891Ssklower 		checkback(s);
29348713Ssklower 	bcopy(old, to, old->siso_len);
29444323Ssklower 	msg.msg_control = 0;
29544323Ssklower 	return (saved_x);
29644323Ssklower }
29748713Ssklower dumpit(what, where, n)
29848713Ssklower char *what; unsigned short *where; int n;
29948713Ssklower {
30048713Ssklower 	unsigned short *s = where;
30148713Ssklower 	unsigned short *z = where + (n+1)/2;
30248713Ssklower 	int count = 0;
303*50891Ssklower 	if (dumpnodata)
30448713Ssklower 		return;
30548713Ssklower 	printf(what);
30648713Ssklower 	while(s < z) {
30748713Ssklower 		count++;
30848713Ssklower 		printf("%x ",*s++);
30948713Ssklower 		if ((count & 15) == 0)
31048713Ssklower 			putchar('\n');
31148713Ssklower 	}
31248713Ssklower 	if (count & 15)
31348713Ssklower 		putchar('\n');
31448713Ssklower 	fflush(stdout);
31548713Ssklower }
31644323Ssklower int *datasize = &iov->iov_len;
31744323Ssklower char *cp, *cplim;
31844323Ssklower 
31944323Ssklower get_control_data(type)
32044323Ssklower {
32144323Ssklower 
32244323Ssklower 	datasize = (int *)&msg.msg_controllen;
32344323Ssklower 	cp = cm.cm.cmdata;
32444323Ssklower 	cplim = cp + sizeof(cm.cm.cmdata);
32544323Ssklower 	cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT;
32644323Ssklower 	cm.cm.cmhdr.cmsg_type = type;
32744323Ssklower 	msg.msg_control = cm.data;
32844323Ssklower }
32944323Ssklower 
33044323Ssklower doconndata(s)
33144323Ssklower {
33244323Ssklower 	get_control_data(TPOPT_CONN_DATA);
33344323Ssklower 	*datasize = strlen(conndata) + sizeof(cm.cm.cmhdr);
33444323Ssklower 	cm.cm.cmhdr.cmsg_len = *datasize;
33544323Ssklower 	bcopy(conndata, cp, *datasize);
33644323Ssklower 	put_record(s, 0);
33744323Ssklower }
33844323Ssklower 
33948713Ssklower get_altbuf(addrbuf)
34048713Ssklower char *addrbuf;
34148713Ssklower {
34248713Ssklower 	if (dgramp == 0) {
34348713Ssklower 		printf("illegal option for stream\n");
34448713Ssklower 		return 1;
34548713Ssklower 	}
34648713Ssklower 	return (scanf("%s", addrbuf) == EOF ? 1 : 0);
34748713Ssklower }
34844323Ssklower 
34944323Ssklower get_record(flags)
35044323Ssklower int *flags;
35144323Ssklower {
35248713Ssklower 	int factor = 1, x = 0, newaddr = 0;
35348713Ssklower 	static repeatcount, repeatsize;
35444323Ssklower 	char workbuf[10240];
35548713Ssklower 	char addrbuf[128];
35644323Ssklower 
35748713Ssklower 	if (repeatcount > 0) {
35848713Ssklower 		repeatcount--;
35948713Ssklower 		return;
36048713Ssklower 	}
36148713Ssklower 
36244323Ssklower 	*flags = 0;
36344323Ssklower 	*datasize = 0;
36444323Ssklower 	datasize = &iov->iov_len;
36544323Ssklower 	cp = data_msg;
36644323Ssklower 	cplim  = cp + sizeof(data_msg);
36744323Ssklower 
36844323Ssklower 	for(;;) {
36944323Ssklower 		x = scanf("%s", workbuf);
37044323Ssklower 		if (x == EOF)
37144323Ssklower 			break;
37248713Ssklower 		if (strcmp(workbuf, "host") == 0) {
37348713Ssklower 			if (get_altbuf(addrbuf))
37448713Ssklower 				break;
37548713Ssklower 			to->siso_addr = *iso_addr(addrbuf);
37648713Ssklower 			newaddr = 1;
37748713Ssklower 		} else if (strcmp(workbuf, "Servername") == 0) {
37848713Ssklower 			if (get_altbuf(Serverbuf))
37948713Ssklower 				break;
38048713Ssklower 			Servername = Serverbuf;
38148713Ssklower 			newaddr = 1;
38248713Ssklower 		} else if (strcmp(workbuf, "port") == 0) {
38348713Ssklower 			x = scanf("%hd", &portnumber);
38448713Ssklower 			if (x == EOF)
38548713Ssklower 				break;
38648713Ssklower 			Servername = 0;
38748713Ssklower 			newaddr = 1;
38848713Ssklower 		} else if (strcmp(workbuf, "repeat") == 0) {
38948713Ssklower 			x = scanf("%d", &repeatcount);
39048713Ssklower 			if (repeatcount <= 0) repeatcount = 1;
39148713Ssklower 			repeatcount--;
39248713Ssklower 			if (x == EOF)
39348713Ssklower 				break;
39448713Ssklower 		} else if (strcmp(workbuf, "disc") == 0)
39544323Ssklower 			x = get_control_data(TPOPT_DISC_DATA);
39644323Ssklower 		else if (strcmp(workbuf, "cfrm") == 0)
39744323Ssklower 			x = get_control_data(TPOPT_CFRM_DATA);
39844323Ssklower 		else if (strcmp(workbuf, "oob") == 0)
39944323Ssklower 			*flags |= MSG_OOB;
40044323Ssklower 		else if (strcmp(workbuf, "eom") == 0)
40144323Ssklower 			*flags |= MSG_EOR;
40244323Ssklower 		else if (strcmp(workbuf, "factor") == 0) {
40344323Ssklower 			x = scanf("%d", &factor);
40444323Ssklower 			if (factor <= 0) factor = 1;
40544323Ssklower 			if (x == EOF)
40644323Ssklower 				break;
40744323Ssklower 		} else {
40844323Ssklower 			int len = strlen(workbuf);
40944323Ssklower 			localsize = 0;
41044323Ssklower 			while ((factor-- > 0) &&
41144323Ssklower 			       ((cp + len) < cplim)) {
41244323Ssklower 					strcpy(cp, workbuf);
41344323Ssklower 					cp += len;
41444323Ssklower 					localsize += len;
41544323Ssklower 			}
41644323Ssklower 			*datasize = localsize;
41744323Ssklower 			if (datasize != &iov->iov_len) {
41844323Ssklower 				*datasize += sizeof(cm.cm.cmhdr);
41948713Ssklower 				repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
42044323Ssklower 			}
42144323Ssklower 			break;
42244323Ssklower 		}
42344323Ssklower 	}
42444323Ssklower 	errno = 0;
42548713Ssklower 	if (newaddr)
42648713Ssklower 		maketoaddr();
42744323Ssklower 	return (x);
42844323Ssklower }
429