xref: /csrg-svn/sys/tests/netccitt/xi_src.c (revision 50424)
149350Ssklower /*-
249353Sbostic  * Copyright (c) 1988, 1991 The Regents of the University of California.
345450Ssklower  * All rights reserved.
445450Ssklower  *
545450Ssklower  * %sccs.include.redist.c%
645450Ssklower  */
749353Sbostic 
849353Sbostic #ifndef lint
949353Sbostic char copyright[] =
1049353Sbostic "@(#) Copyright (c) 1988, 1991 The Regents of the University of California.\n\
1149353Sbostic  All rights reserved.\n";
1249353Sbostic #endif /* not lint */
1349353Sbostic 
1449353Sbostic #ifndef lint
15*50424Ssklower static char sccsid[] = "@(#)xi_src.c	7.6 (Berkeley) 07/15/91";
1649353Sbostic #endif /* not lint */
1749353Sbostic 
1845450Ssklower /*
1948842Ssklower  * This is a test program to be a source for X.25 connections.
2045450Ssklower  */
2145450Ssklower #include <sys/types.h>
2245450Ssklower #include <sys/socket.h>
2345450Ssklower #include <sys/uio.h>
2445450Ssklower #include <sys/ioctl.h>
2545450Ssklower #include <net/route.h>
2645450Ssklower #include <net/if.h>
2745450Ssklower #include <netccitt/x25.h>
2845450Ssklower 
2945450Ssklower #include <stdio.h>
3045450Ssklower #include <errno.h>
3145450Ssklower #include <ctype.h>
3245450Ssklower #include <netdb.h>
3345450Ssklower 
3445450Ssklower 
3545450Ssklower #define dbprintf if(verbose)printf
36*50424Ssklower #ifdef __STDC__
37*50424Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
38*50424Ssklower 		if(x<0) {perror(#a); exit(1);}}
39*50424Ssklower #else
40*50424Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
41*50424Ssklower 		if(x<0) {perror("a"); exit(1);}}
42*50424Ssklower #endif
4345450Ssklower 
4445450Ssklower fd_set	readfds, writefds, exceptfds;
4545450Ssklower long size, count = 10;
4645450Ssklower int verbose = 1, selectp, type = SOCK_STREAM, nobuffs, errno, playtag = 0;
47*50424Ssklower int verify = 0, mqdata, protolisten = 0, echop = 0;
48*50424Ssklower unsigned char protodata[2] = {0, 1};
4945450Ssklower short portnumber = 3000;
5045450Ssklower struct sockaddr_x25 to;
5145450Ssklower char your_it[] = "You're it!";
5245450Ssklower char *port, *conndata, data_msg[2048];
5345450Ssklower struct iovec iov[1] = {data_msg};
5445450Ssklower union {
5545450Ssklower     struct {
5645450Ssklower 	    struct cmsghdr	cmhdr;
5745450Ssklower 	    char		cmdata[128 - sizeof (struct cmsghdr)];
5845450Ssklower     } cm;
5945450Ssklower     char data[128];
6045450Ssklower } cm;
6145450Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
6245450Ssklower 
main(argc,argv)6345450Ssklower main(argc, argv)
6445450Ssklower int argc;
6545450Ssklower char *argv[];
6645450Ssklower {
6745450Ssklower 	register char **av = argv;
6845450Ssklower 	register char *cp;
6945450Ssklower 	u_long len;
7045450Ssklower 	int handy;
7145450Ssklower 
7245450Ssklower 	while(--argc > 0) {
7345450Ssklower 		av++;
7445450Ssklower 		if (strcmp(*av,"dest")==0) {
7545450Ssklower 			av++;
7645450Ssklower 			ccitt_addr(*av, &to);
7745450Ssklower 			argc--;
7845450Ssklower 		} else if (strcmp(*av,"count")==0) {
7945450Ssklower 			av++;
8045450Ssklower 			sscanf(*av,"%ld",&count);
8145450Ssklower 			argc--;
8245450Ssklower 		} else if (strcmp(*av,"size")==0) {
8345450Ssklower 			av++;
8445450Ssklower 			sscanf(*av,"%ld",&size);
85*50424Ssklower 			argc--;
86*50424Ssklower 		} else if (strcmp(*av,"protolisten")==0) {
87*50424Ssklower 			av++;
88*50424Ssklower 			protolisten = 1;
89*50424Ssklower 			sscanf(*av,"%ld",&handy);
90*50424Ssklower 			argc--;
91*50424Ssklower 			protodata[0] = handy;
92*50424Ssklower 		} else if (strcmp(*av,"protonolisten")==0) {
93*50424Ssklower 			av++;
94*50424Ssklower 			protolisten = 1;
95*50424Ssklower 			sscanf(*av,"%ld",&handy);
96*50424Ssklower 			argc--;
97*50424Ssklower 			protodata[0] = handy;
98*50424Ssklower 			protodata[1] = 0;
99*50424Ssklower 		}
10045450Ssklower 	}
10148842Ssklower 	xisrc();
10245450Ssklower }
10345450Ssklower 
xisrc()10448842Ssklower xisrc() {
10545450Ssklower 	int x, s, pid, on = 1, flags = 8, n;
10645450Ssklower 
10745450Ssklower 	try(socket, (AF_CCITT, type, 0),"");
10845450Ssklower 	s = x;
10945450Ssklower 
11045450Ssklower 	/*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/
11145450Ssklower 
112*50424Ssklower 	if (protolisten) {
113*50424Ssklower 		try(setsockopt, (s, CCITTPROTO_X25, PK_PRLISTEN,
114*50424Ssklower 					protodata, sizeof (protodata)), "");
115*50424Ssklower 	    exit(0);
116*50424Ssklower 	}
117*50424Ssklower 
11845450Ssklower 	to.x25_opts.op_flags |= X25_MQBIT;
11945450Ssklower 	try(connect, (s, (struct sockaddr *) &to, to.x25_len), "");
12045450Ssklower 
12145450Ssklower 	if (selectp) {
12245450Ssklower 		FD_ZERO(&writefds); FD_SET(s, &writefds);
12345450Ssklower 		select(1, &writefds, 0, 0, 0);
12445450Ssklower 	}
12545450Ssklower 	while (count-- > 0) {
12645450Ssklower 		if (size <= 0 && get_record(&flags) == EOF)
12745450Ssklower 			exit(0);
12845450Ssklower 		n = put_record(s, flags);
12945450Ssklower 		if (n < iov->iov_len) {
13045450Ssklower 			if (n==-1 && errno == 55) {
13145450Ssklower 				nobuffs++;
13245450Ssklower 				count++;
13345450Ssklower 				continue;
13445450Ssklower 			}
13545450Ssklower 			fprintf(stderr, "wrote %d < %d, count %d,",
13645450Ssklower 						n, iov->iov_len, count);
13745450Ssklower 			perror("due to");
13845450Ssklower 		}
13945450Ssklower 	}
14045450Ssklower 	if (playtag) {
14145450Ssklower 		printf("Tag time!\n");
14245450Ssklower 		iov->iov_base = your_it;
14345450Ssklower 		iov->iov_len = sizeof your_it;
14445450Ssklower 		sendmsg(s, &msg, MSG_EOR);
14545450Ssklower 		sendmsg(s, &msg, MSG_EOR);
14645450Ssklower 		iov->iov_base = data_msg;
14745450Ssklower 		iov->iov_len = sizeof data_msg;
14845450Ssklower 		try(recvmsg, (s, &msg, flags), " playtag ");
14945450Ssklower 	}
15045450Ssklower 	if (nobuffs) {
15145450Ssklower 		printf("looped %d times waiting for bufs\n", nobuffs);
15245450Ssklower 	}
15345450Ssklower }
15445450Ssklower int localsize;
15545450Ssklower char dupbuf[4096];
15645450Ssklower 
157*50424Ssklower struct savebuf {
158*50424Ssklower 	struct savebuf *s_next;
159*50424Ssklower 	struct savebuf *s_prev;
160*50424Ssklower 	int	s_n;
161*50424Ssklower 	int	s_flags;
162*50424Ssklower } savebuf = {&savebuf, &savebuf};
163*50424Ssklower 
164*50424Ssklower void
savedata(n,flags)165*50424Ssklower savedata(n, flags)
166*50424Ssklower int n;
167*50424Ssklower {
168*50424Ssklower 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
169*50424Ssklower 	if (s == 0)
170*50424Ssklower 		return;
171*50424Ssklower 	insque(s, savebuf.s_prev);
172*50424Ssklower 	s->s_n = n;
173*50424Ssklower 	s->s_flags = flags;
174*50424Ssklower 	if (verify)
175*50424Ssklower 		bcopy(iov->iov_base, (char *)(s + 1), n);
176*50424Ssklower }
177*50424Ssklower 
checkback(ns)178*50424Ssklower checkback(ns)
179*50424Ssklower int ns;
180*50424Ssklower {
181*50424Ssklower 	int n;
182*50424Ssklower 	register struct savebuf *s = savebuf.s_next, *t;
183*50424Ssklower 	while (s != &savebuf) {
184*50424Ssklower 		iov->iov_len = s->s_n;
185*50424Ssklower 		n = recvmsg(ns, &msg, s->s_flags);
186*50424Ssklower 		dbprintf("echoed %d\n", n);
187*50424Ssklower 		if (verify &&
188*50424Ssklower 		    (n != s->s_n || bcmp((char *)(s + 1), iov->iov_base, n)))
189*50424Ssklower 			dbprintf("mismatched data or length was %d got %d\n",
190*50424Ssklower 				s->s_n, n);
191*50424Ssklower 		t = s; s = s->s_next; remque(t); free((char *)t);
192*50424Ssklower 	}
193*50424Ssklower }
194*50424Ssklower 
put_record(s,flags)19545450Ssklower put_record(s, flags)
19645450Ssklower int s, flags;
19745450Ssklower {
19845450Ssklower 	int fd, buflen;
19945450Ssklower 	char *buf;
20045450Ssklower 	int x, saved_x;
20145450Ssklower 
20245450Ssklower 	msg.msg_flags = flags;
20345450Ssklower 	if (verbose) {
20445450Ssklower 		unsigned short *zp, *zlim;
20545450Ssklower 		if (msg.msg_controllen) {
20645450Ssklower 			zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len);
20745450Ssklower 			printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
20845450Ssklower 			printf("CMsg data: ");
20945450Ssklower 			x = msg.msg_controllen;
21045450Ssklower 			zlim = zp + ((x + 1) / 2);
21145450Ssklower 			while (zp < zlim) printf("%x ", *zp++);
21245450Ssklower 			putchar ('\n');
21345450Ssklower 		}
21445450Ssklower 		if (iov->iov_len) {
21545450Ssklower 			printf("sending: %s %s",
21645450Ssklower 			(flags & MSG_OOB ? "(OOB Data)" : ""),
21745450Ssklower 				(flags & MSG_EOR ? "(Record Mark)" : ""));
21845450Ssklower 			x = localsize;
21945450Ssklower 			zp = (unsigned short *)data_msg;
22045450Ssklower 			zlim = zp + ((x + 1) / 2);
22145450Ssklower 			while (zp < zlim) printf("%x ", *zp++);
22245450Ssklower 			putchar ('\n');
22345450Ssklower 		}
22445450Ssklower 	}
225*50424Ssklower 	if (echop)
226*50424Ssklower 		savedata(iov->iov_len, flags);
22745450Ssklower 	try(sendmsg, (s, &msg, flags), " put_record ");
22845450Ssklower 	saved_x = x;
229*50424Ssklower 	if (echop && (iov->iov_base[0] & 0x80))
230*50424Ssklower 		checkback(s);
23145450Ssklower 	msg.msg_control = 0;
23245450Ssklower 	return (saved_x);
23345450Ssklower }
23445450Ssklower int *datasize = &iov->iov_len;
23545450Ssklower char *cp, *cplim;
23645450Ssklower 
get_control_data(type,level)23745450Ssklower get_control_data(type, level)
23845450Ssklower {
23945450Ssklower 
24045450Ssklower 	datasize = (int *)&msg.msg_controllen;
24145450Ssklower 	cp = cm.cm.cmdata;
24245450Ssklower 	cplim = cp + sizeof(cm.cm.cmdata);
24345450Ssklower 	cm.cm.cmhdr.cmsg_level = level;
24445450Ssklower 	cm.cm.cmhdr.cmsg_type = type;
24545450Ssklower 	msg.msg_control = cm.data;
24645450Ssklower }
24745450Ssklower 
24845450Ssklower 
24945450Ssklower 
get_record(flags)25045450Ssklower get_record(flags)
25145450Ssklower int *flags;
25245450Ssklower {
25345450Ssklower 	int factor = 1, x = 0;
25445450Ssklower 	char workbuf[10240];
25548842Ssklower 	static repeatcount, repeatsize;
25645450Ssklower 
25748842Ssklower 	if (repeatcount > 0) {
25848842Ssklower 		repeatcount--;
25948842Ssklower 		return;
26048842Ssklower 	}
26145450Ssklower 	*flags = 0;
26245450Ssklower 	*datasize = 0;
26345450Ssklower 	datasize = &iov->iov_len;
26445450Ssklower 	cp = data_msg + 1;
26545572Ssklower 	cplim  = data_msg + sizeof(data_msg);
26645450Ssklower 
26745572Ssklower 	*data_msg = 0;
26845450Ssklower 	for(;;) {
26945450Ssklower 		x = scanf("%s", workbuf);
27045450Ssklower 		if (x == EOF)
27145450Ssklower 			break;
27245450Ssklower 		if (strcmp(workbuf, "oob") == 0)
27345450Ssklower 			*flags |= MSG_OOB;
27445450Ssklower 		else if (strcmp(workbuf, "qbit") == 0)
27545450Ssklower 			*data_msg |= 0x80;
27645450Ssklower 		else if (strcmp(workbuf, "mbit") == 0)
27745450Ssklower 			*data_msg |= 0x40;
27845450Ssklower 		else if (strcmp(workbuf, "eom") == 0)
27945450Ssklower 			*flags |= MSG_EOR;
28045450Ssklower 		else if (strcmp(workbuf, "factor") == 0) {
28145450Ssklower 			x = scanf("%d", &factor);
28245450Ssklower 			if (factor <= 0) factor = 1;
28345450Ssklower 			if (x == EOF)
28445450Ssklower 				break;
28548842Ssklower 		} else if (strcmp(workbuf, "repeat") == 0) {
28648842Ssklower 			x = scanf("%d", &repeatcount);
28748842Ssklower 			if (repeatcount <= 0) repeatcount = 1;
28848842Ssklower 			if (x == EOF)
28948842Ssklower 				break;
29045450Ssklower 		} else {
29145450Ssklower 			int len = strlen(workbuf);
29245572Ssklower 			localsize = 1;
29345450Ssklower 			while ((factor-- > 0) &&
29445450Ssklower 			       ((cp + len) < cplim)) {
29545450Ssklower 					strcpy(cp, workbuf);
29645450Ssklower 					cp += len;
29745450Ssklower 					localsize += len;
29845450Ssklower 			}
29945450Ssklower 			*datasize = localsize;
30045450Ssklower 			if (datasize != &iov->iov_len) {
30145450Ssklower 				*datasize += sizeof(cm.cm.cmhdr);
30248842Ssklower 				repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
30345450Ssklower 			}
30445450Ssklower 			break;
30545450Ssklower 		}
30645450Ssklower 	}
30745450Ssklower 	errno = 0;
30845450Ssklower 	return (x);
30945450Ssklower }
310