xref: /original-bsd/sys/tests/netccitt/xi_src.c (revision ba762ddc)
1 /*
2  * Copyright (c) 1988, 1990 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 #ifndef lint
8 static char sccsid[] = "@(#)xi_src.c	7.3 (Berkeley) 04/29/91";
9 #endif /* not lint */
10 
11 /*
12  * This is a test program to be a source for X.25 connections.
13  */
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/uio.h>
17 #include <sys/ioctl.h>
18 #include <net/route.h>
19 #include <net/if.h>
20 #include <netccitt/x25.h>
21 
22 #include <stdio.h>
23 #include <errno.h>
24 #include <ctype.h>
25 #include <netdb.h>
26 
27 
28 #define dbprintf if(verbose)printf
29 #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\
30 		    if (x < 0) {perror("a"); exit(1);}}
31 
32 fd_set	readfds, writefds, exceptfds;
33 long size, count = 10;
34 int verbose = 1, selectp, type = SOCK_STREAM, nobuffs, errno, playtag = 0;
35 int verify = 0, mqdata;
36 short portnumber = 3000;
37 struct sockaddr_x25 to;
38 char your_it[] = "You're it!";
39 char *port, *conndata, data_msg[2048];
40 struct iovec iov[1] = {data_msg};
41 union {
42     struct {
43 	    struct cmsghdr	cmhdr;
44 	    char		cmdata[128 - sizeof (struct cmsghdr)];
45     } cm;
46     char data[128];
47 } cm;
48 struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
49 
50 main(argc, argv)
51 int argc;
52 char *argv[];
53 {
54 	register char **av = argv;
55 	register char *cp;
56 	u_long len;
57 	int handy;
58 
59 	while(--argc > 0) {
60 		av++;
61 		if (strcmp(*av,"dest")==0) {
62 			av++;
63 			ccitt_addr(*av, &to);
64 			argc--;
65 		} else if (strcmp(*av,"count")==0) {
66 			av++;
67 			sscanf(*av,"%ld",&count);
68 			argc--;
69 		} else if (strcmp(*av,"size")==0) {
70 			av++;
71 			sscanf(*av,"%ld",&size);
72 		}
73 	}
74 	xisrc();
75 }
76 
77 xisrc() {
78 	int x, s, pid, on = 1, flags = 8, n;
79 
80 	try(socket, (AF_CCITT, type, 0),"");
81 	s = x;
82 
83 	/*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/
84 
85 	to.x25_opts.op_flags |= X25_MQBIT;
86 	try(connect, (s, (struct sockaddr *) &to, to.x25_len), "");
87 
88 	if (selectp) {
89 		FD_ZERO(&writefds); FD_SET(s, &writefds);
90 		select(1, &writefds, 0, 0, 0);
91 	}
92 	while (count-- > 0) {
93 		if (size <= 0 && get_record(&flags) == EOF)
94 			exit(0);
95 		n = put_record(s, flags);
96 		if (n < iov->iov_len) {
97 			if (n==-1 && errno == 55) {
98 				nobuffs++;
99 				count++;
100 				continue;
101 			}
102 			fprintf(stderr, "wrote %d < %d, count %d,",
103 						n, iov->iov_len, count);
104 			perror("due to");
105 		}
106 	}
107 	if (playtag) {
108 		printf("Tag time!\n");
109 		iov->iov_base = your_it;
110 		iov->iov_len = sizeof your_it;
111 		sendmsg(s, &msg, MSG_EOR);
112 		sendmsg(s, &msg, MSG_EOR);
113 		iov->iov_base = data_msg;
114 		iov->iov_len = sizeof data_msg;
115 		try(recvmsg, (s, &msg, flags), " playtag ");
116 	}
117 	if (nobuffs) {
118 		printf("looped %d times waiting for bufs\n", nobuffs);
119 	}
120 }
121 int localsize;
122 char dupbuf[4096];
123 
124 put_record(s, flags)
125 int s, flags;
126 {
127 	int fd, buflen;
128 	char *buf;
129 	int x, saved_x;
130 
131 	msg.msg_flags = flags;
132 	if (verbose) {
133 		unsigned short *zp, *zlim;
134 		if (msg.msg_controllen) {
135 			zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len);
136 			printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
137 			printf("CMsg data: ");
138 			x = msg.msg_controllen;
139 			zlim = zp + ((x + 1) / 2);
140 			while (zp < zlim) printf("%x ", *zp++);
141 			putchar ('\n');
142 		}
143 		if (iov->iov_len) {
144 			printf("sending: %s %s",
145 			(flags & MSG_OOB ? "(OOB Data)" : ""),
146 				(flags & MSG_EOR ? "(Record Mark)" : ""));
147 			x = localsize;
148 			zp = (unsigned short *)data_msg;
149 			zlim = zp + ((x + 1) / 2);
150 			while (zp < zlim) printf("%x ", *zp++);
151 			putchar ('\n');
152 		}
153 	}
154 	if (verify) {
155 		buflen = iov->iov_len;
156 		bcopy(iov->iov_base, dupbuf, buflen);
157 	}
158 	try(sendmsg, (s, &msg, flags), " put_record ");
159 	saved_x = x;
160 	while (verify && buflen > 0) {
161 		iov->iov_len = buflen;
162 		iov->iov_base = dupbuf;
163 		try(recvmsg, (s, &msg, flags), " put_record ");
164 		printf("verify got %d\n", x);
165 		buflen -= x;
166 	}
167 	msg.msg_control = 0;
168 	return (saved_x);
169 }
170 int *datasize = &iov->iov_len;
171 char *cp, *cplim;
172 
173 get_control_data(type, level)
174 {
175 
176 	datasize = (int *)&msg.msg_controllen;
177 	cp = cm.cm.cmdata;
178 	cplim = cp + sizeof(cm.cm.cmdata);
179 	cm.cm.cmhdr.cmsg_level = level;
180 	cm.cm.cmhdr.cmsg_type = type;
181 	msg.msg_control = cm.data;
182 }
183 
184 
185 
186 get_record(flags)
187 int *flags;
188 {
189 	int factor = 1, x = 0;
190 	char workbuf[10240];
191 	static repeatcount, repeatsize;
192 
193 	if (repeatcount > 0) {
194 		repeatcount--;
195 		return;
196 	}
197 	*flags = 0;
198 	*datasize = 0;
199 	datasize = &iov->iov_len;
200 	cp = data_msg + 1;
201 	cplim  = data_msg + sizeof(data_msg);
202 
203 	*data_msg = 0;
204 	for(;;) {
205 		x = scanf("%s", workbuf);
206 		if (x == EOF)
207 			break;
208 		if (strcmp(workbuf, "oob") == 0)
209 			*flags |= MSG_OOB;
210 		else if (strcmp(workbuf, "qbit") == 0)
211 			*data_msg |= 0x80;
212 		else if (strcmp(workbuf, "mbit") == 0)
213 			*data_msg |= 0x40;
214 		else if (strcmp(workbuf, "eom") == 0)
215 			*flags |= MSG_EOR;
216 		else if (strcmp(workbuf, "factor") == 0) {
217 			x = scanf("%d", &factor);
218 			if (factor <= 0) factor = 1;
219 			if (x == EOF)
220 				break;
221 		} else if (strcmp(workbuf, "repeat") == 0) {
222 			x = scanf("%d", &repeatcount);
223 			if (repeatcount <= 0) repeatcount = 1;
224 			if (x == EOF)
225 				break;
226 		} else {
227 			int len = strlen(workbuf);
228 			localsize = 1;
229 			while ((factor-- > 0) &&
230 			       ((cp + len) < cplim)) {
231 					strcpy(cp, workbuf);
232 					cp += len;
233 					localsize += len;
234 			}
235 			*datasize = localsize;
236 			if (datasize != &iov->iov_len) {
237 				*datasize += sizeof(cm.cm.cmhdr);
238 				repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
239 			}
240 			break;
241 		}
242 	}
243 	errno = 0;
244 	return (x);
245 }
246