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