xref: /csrg-svn/sys/tests/netiso/tisrc.c (revision 58241)
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*58241Ssklower static char sccsid[] = "@(#)tisrc.c	7.8 (Berkeley) 02/25/93";
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
3850891Ssklower #ifdef __STDC__
3950891Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
4050891Ssklower 		if (x<0) {perror(#a); exit(1);}}
4150891Ssklower #else
4250891Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
4350891Ssklower 		if (x<0) {perror("a");exit(1);}}
4450891Ssklower #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;
49*58241Ssklower struct  sockaddr_iso from_s = { sizeof(from_s), AF_ISO }, *from = 0;
5048713Ssklower struct  sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s;
5148843Ssklower struct	tp_conn_param tp_params;
5244323Ssklower fd_set	readfds, writefds, exceptfds;
5350891Ssklower long size, count = 0;
54*58241Ssklower int verbose = 1, selectp, socktype = SOCK_SEQPACKET, nobuffs, errno, playtag = 0;
55*58241Ssklower int echop = 0, dgramp = 0, debug = 0, tp0mode = 0, dumpnodata  = 0, tuba = 0;
5644323Ssklower short portnumber = 3000;
5744323Ssklower char your_it[] = "You're it!";
5850891Ssklower char *Servername, *conndata, data_msg[8192];
5948713Ssklower char Serverbuf[128];
6048713Ssklower char name[128];
6144323Ssklower struct iovec iov[1] = {data_msg};
6244323Ssklower union {
6344323Ssklower     struct {
6444323Ssklower 	    struct cmsghdr	cmhdr;
6548713Ssklower 	    char		cmdata[128 - sizeof(struct cmsghdr)];
6644323Ssklower     } cm;
6744323Ssklower     char data[128];
6844323Ssklower } cm;
6944323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
7044323Ssklower 
main(argc,argv)7144323Ssklower main(argc, argv)
7244323Ssklower int argc;
7344323Ssklower char *argv[];
7444323Ssklower {
7544323Ssklower 	register char **av = argv;
7644323Ssklower 	register char *cp;
7744323Ssklower 	u_long len;
7844323Ssklower 	int handy;
7944323Ssklower 
8044323Ssklower 	while(--argc > 0) {
8144323Ssklower 		av++;
8244323Ssklower 		if(strcmp(*av,"Servername")==0) {
8344323Ssklower 			av++;
8448713Ssklower 			Servername = *av;
8544323Ssklower 			argc--;
8644323Ssklower 		} else if(strcmp(*av,"conndata")==0) {
8744323Ssklower 			av++;
8844323Ssklower 			conndata = *av;
8944323Ssklower 			argc--;
9044323Ssklower 		} else if(strcmp(*av,"host")==0) {
9144323Ssklower 			av++;
9248713Ssklower 			to_s.siso_addr = *iso_addr(*av);
9344323Ssklower 			argc--;
94*58241Ssklower 		} else if(strcmp(*av,"from")==0) {
95*58241Ssklower 			av++;
96*58241Ssklower 			from_s.siso_addr = *iso_addr(*av);
97*58241Ssklower 			from = &from_s;
98*58241Ssklower 			argc--;
9944323Ssklower 		} else if(strcmp(*av,"port")==0) {
10044323Ssklower 			av++;
10144323Ssklower 			sscanf(*av,"%hd",&portnumber);
10244323Ssklower 			argc--;
10344323Ssklower 		} else if(strcmp(*av,"count")==0) {
10444323Ssklower 			av++;
10544323Ssklower 			sscanf(*av,"%ld",&count);
10644323Ssklower 			argc--;
10744323Ssklower 		} else if(strcmp(*av,"size")==0) {
10844323Ssklower 			av++;
10944323Ssklower 			sscanf(*av,"%ld",&size);
11044323Ssklower 			iov->iov_len = size;
11144323Ssklower 		} else if(strcmp(*av,"stream")==0) {
112*58241Ssklower 			socktype = SOCK_STREAM;
11350891Ssklower 		} else if (strcmp(*av, "echo")==0) {
11450891Ssklower 			echop++;
11544323Ssklower 		} else if (strcmp(*av,"eon") == 0) {
11644323Ssklower 			unsigned long l, inet_addr();
11744323Ssklower 
11844323Ssklower 			l = inet_addr(*++av); argc--;
11944323Ssklower 			to_s.siso_addr = eon;
12044323Ssklower 			bcopy((char *)&l, &to_s.siso_data[15], 4);
12144323Ssklower 		}
12244323Ssklower 	}
12348713Ssklower 	maketoaddr();
12448713Ssklower 	tisrc();
12548713Ssklower }
12648713Ssklower 
maketoaddr()12748713Ssklower maketoaddr()
12848713Ssklower {
12948713Ssklower 	if (Servername) {
13048713Ssklower 		int tlen = strlen(Servername);
13148713Ssklower 		int len =  tlen + TSEL(to) - (caddr_t) to;
13248713Ssklower 		if (len < sizeof(*to)) len = sizeof(*to);
13348713Ssklower 		if (len > to->siso_len) {
13449065Ssklower 			old = to;
13544323Ssklower 			to = (struct sockaddr_iso *)malloc(len);
13649065Ssklower 			*to = *old; /* We dont care if all old tsel is copied*/
13749065Ssklower 			if (old != &to_s) free(old);
13844323Ssklower 		}
13949065Ssklower 		bcopy(Servername, TSEL(to), tlen);
14049065Ssklower 		to->siso_tlen = tlen;
14144323Ssklower 	} else {
14249065Ssklower 		to->siso_tlen = sizeof(portnumber);
14344323Ssklower 		portnumber = htons(portnumber);
14449065Ssklower 		bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber));
14544323Ssklower 	}
14644323Ssklower }
14744323Ssklower 
tisrc()14844323Ssklower tisrc() {
149*58241Ssklower 	int x, s, pid, on = 1, flags = 8, n;
150*58241Ssklower 	int proto = (tp0mode ? ISOPROTO_TP0 : (tuba ? ISOPROTO_TCP : 0 ));
151*58241Ssklower 	int socktype = (dgramp ? SOCK_DGRAM :
152*58241Ssklower 			(tuba ? SOCK_STREAM :SOCK_SEQPACKET));
15344323Ssklower 
154*58241Ssklower 	try(socket, (AF_ISO, socktype, proto),"");
15544323Ssklower 	s = x;
15644323Ssklower 
15748713Ssklower 	if (debug)
15848713Ssklower 		try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), "");
15948713Ssklower 	if (dgramp == 0) {
16048713Ssklower 		if (conndata)
16148713Ssklower 			doconndata(s);
162*58241Ssklower 		if (from) {
163*58241Ssklower 			try(bind,
164*58241Ssklower 			    (s, (struct sockaddr *)from, from->siso_len), "");
165*58241Ssklower 		}
16648713Ssklower 		try(connect, (s, (struct sockaddr *) to, to->siso_len), "");
16750891Ssklower 		recv_cdata(s);
16848713Ssklower 	}
16944323Ssklower 	if (selectp) {
17044323Ssklower 		FD_ZERO(&writefds); FD_SET(s, &writefds);
17144323Ssklower 		select(1, &writefds, 0, 0, 0);
17244323Ssklower 	}
17350891Ssklower 	do {
17444323Ssklower 		if (size <= 0 && get_record(&flags) == EOF)
17544323Ssklower 			exit(0);
17644323Ssklower 		n = put_record(s, flags);
17744323Ssklower 		if (n < iov->iov_len) {
17850891Ssklower 			if (n == -1 && errno == 55) {
17944323Ssklower 				nobuffs++;
18050891Ssklower 				if (count) ++count;
18144323Ssklower 				continue;
18244323Ssklower 			}
18344323Ssklower 			fprintf(stderr, "wrote %d < %d, count %d,",
18444323Ssklower 						n, iov->iov_len, count);
18544323Ssklower 			perror("due to");
18644323Ssklower 		}
18750891Ssklower 	} while (count == 0 || --count >= 1);
18844323Ssklower 	if (playtag) {
18944323Ssklower 		printf("Tag time!\n");
19044323Ssklower 		iov->iov_base = your_it;
19144323Ssklower 		iov->iov_len = sizeof your_it;
19244323Ssklower 		sendmsg(s, &msg, MSG_EOR);
19344323Ssklower 		sendmsg(s, &msg, MSG_EOR);
19444323Ssklower 		iov->iov_base = data_msg;
19544323Ssklower 		iov->iov_len = sizeof data_msg;
19644323Ssklower 		try(recvmsg, (s, &msg, flags), " playtag ");
19744323Ssklower 	}
19844323Ssklower 	if(nobuffs) {
19944323Ssklower 		printf("looped %d times waiting for bufs\n", nobuffs);
20044323Ssklower 	}
20144323Ssklower }
20250891Ssklower 
recv_cdata(s)20350891Ssklower recv_cdata(s)
20450891Ssklower int s;
20550891Ssklower {
20650891Ssklower 	int x;
20750891Ssklower 	iov->iov_len = 0;
20850891Ssklower 	msg.msg_controllen = sizeof(cm);
20950891Ssklower 	msg.msg_control = (char *)&cm;
21050891Ssklower 	try(recvmsg,(s, &msg, 0), "confirm data?");
21150891Ssklower 	if (msg.msg_controllen)
21250891Ssklower 		dumpit("", (u_short *)&cm, msg.msg_controllen);
21350891Ssklower 	msg.msg_control = 0;
21450891Ssklower 	msg.msg_controllen = 0;
21550891Ssklower }
21650891Ssklower 
21744323Ssklower int localsize;
21844323Ssklower char dupbuf[4096];
21944323Ssklower 
22050891Ssklower struct savebuf {
22150891Ssklower 	struct savebuf *s_next;
22250891Ssklower 	struct savebuf *s_prev;
22350891Ssklower 	int	s_n;
22450891Ssklower 	int	s_flags;
22550891Ssklower } savebuf = {&savebuf, &savebuf};
22650891Ssklower 
22750891Ssklower void
savedata(n,flags)22850891Ssklower savedata(n, flags)
22950891Ssklower int n;
23050891Ssklower {
23150891Ssklower 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
23250891Ssklower 	if (s == 0)
23350891Ssklower 		return;
23450891Ssklower 	insque(s, savebuf.s_prev);
23550891Ssklower 	s->s_n = n;
23650891Ssklower 	s->s_flags = flags;
23750891Ssklower 	bcopy(iov->iov_base, (char *)(s + 1), n);
23850891Ssklower }
23950891Ssklower 
checkback(fd)24053366Ssklower checkback(fd)
24153366Ssklower int fd;
24250891Ssklower {
24350891Ssklower 	int n, nn;
24450891Ssklower 	register struct savebuf *s = savebuf.s_next, *t;
24550891Ssklower 	register char *cp = data_msg;
24650891Ssklower 	while (s != &savebuf) {
24750891Ssklower 		nn = s->s_n;
24850891Ssklower 		do {
24950891Ssklower 			msg.msg_flags = 0;
25050891Ssklower 			iov->iov_len = nn;
25150891Ssklower 			iov->iov_base = cp;
25253366Ssklower 			n = recvmsg(fd, &msg, 0);
25350891Ssklower 			cp += n;
25450891Ssklower 			nn -= n;
25550891Ssklower 		} while (dgramp == 0 && nn > 0 && !(msg.msg_flags & MSG_EOR));
25650891Ssklower 		iov->iov_base = data_msg;
25750891Ssklower 		if (dgramp) {
25850891Ssklower 			if (msg.msg_namelen)
25950891Ssklower 				dumpit("from: ", to, msg.msg_namelen);
26050891Ssklower 			msg.msg_namelen = old->siso_len;
26150891Ssklower 		}
26250891Ssklower 		n = s->s_n - nn;
26350891Ssklower 		dbprintf("echoed %d", n);
26450891Ssklower 		if (nn)
26550891Ssklower 			dbprintf(" instead of %d", s->s_n);
26650891Ssklower 		if (bcmp((char *)(s + 1), data_msg, n))
26750891Ssklower 			dbprintf(", with mismatched data");
26850891Ssklower 		if (nn && (msg.msg_flags & MSG_EOR))
26950891Ssklower 			dbprintf(" and with %d unchecked after EOR", nn);
27050891Ssklower 		dbprintf("\n");
27150891Ssklower 		t = s; s = s->s_next; remque(t); free((char *)t);
27250891Ssklower 	}
27350891Ssklower }
27450891Ssklower 
27550891Ssklower 
put_record(s,flags)27644323Ssklower put_record(s, flags)
27744323Ssklower int s, flags;
27844323Ssklower {
27944323Ssklower 	char *buf;
28044323Ssklower 	int x, saved_x;
28144323Ssklower 
28244323Ssklower 	msg.msg_flags = flags;
28344323Ssklower 	if (verbose) {
28444323Ssklower 		if (msg.msg_controllen) {
28544323Ssklower 			printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
28648713Ssklower 			dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen);
28744323Ssklower 		}
28844323Ssklower 		if (iov->iov_len) {
28944323Ssklower 			printf("sending: %s %s",
29044323Ssklower 			(flags & MSG_OOB ? "(OOB Data)" : ""),
29144323Ssklower 				(flags & MSG_EOR ? "(Record Mark)" : ""));
29248713Ssklower 			dumpit("data: ", data_msg, localsize);
29344323Ssklower 		}
29444323Ssklower 	}
29550891Ssklower 	if (echop)
29650891Ssklower 		savedata(iov->iov_len, flags);
29748713Ssklower 	if (dgramp) {
29848713Ssklower 		msg.msg_name = (caddr_t)to;
29948713Ssklower 		msg.msg_namelen = to->siso_len;
30048713Ssklower 	}
30144323Ssklower 	try(sendmsg, (s, &msg, flags), " put_record ");
30244323Ssklower 	saved_x = x;
30350891Ssklower 	if (echop && (flags & MSG_EOR))
30450891Ssklower 		checkback(s);
30548713Ssklower 	bcopy(old, to, old->siso_len);
30644323Ssklower 	msg.msg_control = 0;
30744323Ssklower 	return (saved_x);
30844323Ssklower }
dumpit(what,where,n)30948713Ssklower dumpit(what, where, n)
31048713Ssklower char *what; unsigned short *where; int n;
31148713Ssklower {
31248713Ssklower 	unsigned short *s = where;
31348713Ssklower 	unsigned short *z = where + (n+1)/2;
31448713Ssklower 	int count = 0;
31550891Ssklower 	if (dumpnodata)
31648713Ssklower 		return;
31748713Ssklower 	printf(what);
31848713Ssklower 	while(s < z) {
31948713Ssklower 		count++;
32048713Ssklower 		printf("%x ",*s++);
32148713Ssklower 		if ((count & 15) == 0)
32248713Ssklower 			putchar('\n');
32348713Ssklower 	}
32448713Ssklower 	if (count & 15)
32548713Ssklower 		putchar('\n');
32648713Ssklower 	fflush(stdout);
32748713Ssklower }
32844323Ssklower int *datasize = &iov->iov_len;
32944323Ssklower char *cp, *cplim;
33044323Ssklower 
get_control_data(type)33144323Ssklower get_control_data(type)
33244323Ssklower {
33344323Ssklower 
33444323Ssklower 	datasize = (int *)&msg.msg_controllen;
33544323Ssklower 	cp = cm.cm.cmdata;
33644323Ssklower 	cplim = cp + sizeof(cm.cm.cmdata);
33744323Ssklower 	cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT;
33844323Ssklower 	cm.cm.cmhdr.cmsg_type = type;
33944323Ssklower 	msg.msg_control = cm.data;
34044323Ssklower }
34144323Ssklower 
doconndata(s)34244323Ssklower doconndata(s)
34344323Ssklower {
34444323Ssklower 	get_control_data(TPOPT_CONN_DATA);
34544323Ssklower 	*datasize = strlen(conndata) + sizeof(cm.cm.cmhdr);
34644323Ssklower 	cm.cm.cmhdr.cmsg_len = *datasize;
34744323Ssklower 	bcopy(conndata, cp, *datasize);
34844323Ssklower 	put_record(s, 0);
34944323Ssklower }
35044323Ssklower 
get_altbuf(addrbuf)35148713Ssklower get_altbuf(addrbuf)
35248713Ssklower char *addrbuf;
35348713Ssklower {
35448713Ssklower 	if (dgramp == 0) {
35548713Ssklower 		printf("illegal option for stream\n");
35648713Ssklower 		return 1;
35748713Ssklower 	}
35848713Ssklower 	return (scanf("%s", addrbuf) == EOF ? 1 : 0);
35948713Ssklower }
36044323Ssklower 
get_record(flags)36144323Ssklower get_record(flags)
36244323Ssklower int *flags;
36344323Ssklower {
36448713Ssklower 	int factor = 1, x = 0, newaddr = 0;
36548713Ssklower 	static repeatcount, repeatsize;
36644323Ssklower 	char workbuf[10240];
36748713Ssklower 	char addrbuf[128];
36844323Ssklower 
36948713Ssklower 	if (repeatcount > 0) {
37048713Ssklower 		repeatcount--;
37148713Ssklower 		return;
37248713Ssklower 	}
37348713Ssklower 
37444323Ssklower 	*flags = 0;
37544323Ssklower 	*datasize = 0;
37644323Ssklower 	datasize = &iov->iov_len;
37744323Ssklower 	cp = data_msg;
37844323Ssklower 	cplim  = cp + sizeof(data_msg);
37944323Ssklower 
38044323Ssklower 	for(;;) {
38144323Ssklower 		x = scanf("%s", workbuf);
38244323Ssklower 		if (x == EOF)
38344323Ssklower 			break;
38448713Ssklower 		if (strcmp(workbuf, "host") == 0) {
38548713Ssklower 			if (get_altbuf(addrbuf))
38648713Ssklower 				break;
38748713Ssklower 			to->siso_addr = *iso_addr(addrbuf);
38848713Ssklower 			newaddr = 1;
38948713Ssklower 		} else if (strcmp(workbuf, "Servername") == 0) {
39048713Ssklower 			if (get_altbuf(Serverbuf))
39148713Ssklower 				break;
39248713Ssklower 			Servername = Serverbuf;
39348713Ssklower 			newaddr = 1;
39448713Ssklower 		} else if (strcmp(workbuf, "port") == 0) {
39548713Ssklower 			x = scanf("%hd", &portnumber);
39648713Ssklower 			if (x == EOF)
39748713Ssklower 				break;
39848713Ssklower 			Servername = 0;
39948713Ssklower 			newaddr = 1;
40048713Ssklower 		} else if (strcmp(workbuf, "repeat") == 0) {
40148713Ssklower 			x = scanf("%d", &repeatcount);
40248713Ssklower 			if (repeatcount <= 0) repeatcount = 1;
40348713Ssklower 			repeatcount--;
40448713Ssklower 			if (x == EOF)
40548713Ssklower 				break;
40648713Ssklower 		} else if (strcmp(workbuf, "disc") == 0)
40744323Ssklower 			x = get_control_data(TPOPT_DISC_DATA);
40844323Ssklower 		else if (strcmp(workbuf, "cfrm") == 0)
40944323Ssklower 			x = get_control_data(TPOPT_CFRM_DATA);
41044323Ssklower 		else if (strcmp(workbuf, "oob") == 0)
41144323Ssklower 			*flags |= MSG_OOB;
41244323Ssklower 		else if (strcmp(workbuf, "eom") == 0)
41344323Ssklower 			*flags |= MSG_EOR;
41444323Ssklower 		else if (strcmp(workbuf, "factor") == 0) {
41544323Ssklower 			x = scanf("%d", &factor);
41644323Ssklower 			if (factor <= 0) factor = 1;
41744323Ssklower 			if (x == EOF)
41844323Ssklower 				break;
41944323Ssklower 		} else {
42044323Ssklower 			int len = strlen(workbuf);
42144323Ssklower 			localsize = 0;
42244323Ssklower 			while ((factor-- > 0) &&
42344323Ssklower 			       ((cp + len) < cplim)) {
42444323Ssklower 					strcpy(cp, workbuf);
42544323Ssklower 					cp += len;
42644323Ssklower 					localsize += len;
42744323Ssklower 			}
42844323Ssklower 			*datasize = localsize;
42944323Ssklower 			if (datasize != &iov->iov_len) {
43044323Ssklower 				*datasize += sizeof(cm.cm.cmhdr);
43148713Ssklower 				repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
43244323Ssklower 			}
43344323Ssklower 			break;
43444323Ssklower 		}
43544323Ssklower 	}
43644323Ssklower 	errno = 0;
43748713Ssklower 	if (newaddr)
43848713Ssklower 		maketoaddr();
43944323Ssklower 	return (x);
44044323Ssklower }
441