xref: /original-bsd/sys/tests/netiso/tisink.c (revision 6093a5ae)
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[] = "@(#)tisink.c	7.10 (Berkeley) 07/23/92";
16 #endif /* not lint */
17 
18 /*
19  * This is a test program to be a sink for ISO packets.
20  */
21 #include <unistd.h>
22 #include <sys/param.h>
23 #include <sys/uio.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/syscall.h>
27 #include <net/route.h>
28 #include <net/if.h>
29 #define  TCPT_NTIMERS 4
30 #include <netiso/iso.h>
31 #include <netiso/tp_param.h>
32 #include <netiso/tp_user.h>
33 
34 #include <stdio.h>
35 #include <errno.h>
36 #include <ctype.h>
37 #include <netdb.h>
38 
39 
40 #define dbprintf if(verbose)printf
41 #ifdef __STDC__
42 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
43 		if (x<0) {perror(#a); myexit(0);}}
44 #else
45 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
46 		if (x<0) {perror("a"); myexit(0);}}
47 #endif
48 
49 
50 struct  ifreq ifr;
51 short port = 3000;
52 struct  sockaddr_iso faddr, laddr = { sizeof(laddr), AF_ISO };
53 struct  sockaddr_iso *siso = &laddr;
54 char **xenvp;
55 
56 long size, forkp = 0, confp = 0, mynamep, verbose = 1, echop = 0;
57 long records, intercept = 0, isode_mode = 0, dgramp = 0, tp0mode = 0;
58 long dumpnodata = 0, playtag = 0, select_mode = 0;
59 void savedata();
60 
61 char buf[2048];
62 char your_it[] = "You're it!";
63 fd_set readfds, exceptfds;
64 
65 char *Servername;
66 
67 main(argc, argv, envp)
68 int argc;
69 char *argv[];
70 char *envp[];
71 {
72 	register char **av = argv;
73 	register char *cp;
74 	struct iso_addr *iso_addr();
75 
76 	xenvp = envp;
77 	while(--argc > 0) {
78 		av++;
79 		if(strcmp(*av,"Servername")==0) {
80 			av++;
81 			Servername = *av;
82 			argc--;
83 		} else if (strcmp(*av,"host")==0) {
84 			av++;
85 			laddr.siso_addr = *iso_addr(*av);
86 			argc--;
87 		} else if (strcmp(*av,"port")==0) {
88 			av++;
89 			sscanf(*av,"%hd",&port);
90 			argc--;
91 		} else if (strcmp(*av,"size")==0) {
92 			av++;
93 			sscanf(*av,"%ld",&size);
94 			argc--;
95 		} else if (strcmp(*av, "echo")==0) {
96 			echop++;
97 		} else if (strcmp(*av, "intercept")==0) {
98 			intercept++;
99 		}
100 	}
101 	if (Servername) {
102 		int tlen = laddr.siso_tlen = strlen(Servername);
103 		int len =  TSEL(siso) + tlen - (caddr_t) &siso;
104 		if (len > sizeof(*siso)) {
105 			siso = (struct sockaddr_iso *)malloc(len);
106 			*siso = laddr;
107 			siso->siso_len = len;
108 		}
109 		bcopy(Servername, TSEL(siso), tlen);
110 	} else {
111 		port = htons(port);
112 		laddr.siso_tlen = sizeof(port);
113 		bcopy((char *)&port, TSEL(siso), sizeof(port));
114 	}
115 	tisink();
116 }
117 #define BIG 2048
118 #define MIDLIN 512
119 char readbuf[BIG];
120 struct iovec iov[1] = {
121 	readbuf,
122 	sizeof readbuf,
123 };
124 char name[MIDLIN];
125 union {
126     struct {
127 	    struct cmsghdr	cmhdr;
128 	    char		cmdata[128 - sizeof(struct cmsghdr)];
129     } cm;
130     char data[128];
131 } cbuf;
132 #define control cbuf.data
133 struct msghdr msghdr = {
134 	name, sizeof(name),
135 	iov, sizeof(iov)/sizeof(iov[1]),
136 	control, sizeof control,
137 	0 /* flags */
138 };
139 
140 tisink()
141 {
142 	int x, s, pid, on = 1, loop = 0, n, ns;
143 	extern int errno;
144 	int socktype = (dgramp ? SOCK_DGRAM : SOCK_SEQPACKET);
145 	int proto = (tp0mode ? ISOPROTO_TP0 : 0 );
146 	int addrlen = sizeof(faddr);
147 
148 	try(socket, (AF_ISO, socktype, proto),"");
149 
150 	s = x;
151 
152 	try(bind, (s, (struct sockaddr *) siso, siso->siso_len), "");
153 
154 	/*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */
155 	if (dgramp) {
156 		ns  =  s;
157 		goto dgram1;
158 	}
159 
160 	try(listen, (s, 5), "");
161 	if (intercept) {
162 	    try(setsockopt,
163 		(s, SOL_TRANSPORT, TPOPT_INTERCEPT, &on, sizeof(on)), "");
164 	}
165 	for(;;) {
166 		int child;
167 		char childname[50];
168 
169 		try (accept, (s, (struct sockaddr *)&faddr, &addrlen), "");
170 		ns = x;
171 		dumpit("connection from:", &faddr, sizeof faddr);
172 		if (mynamep || intercept) {
173 			addrlen = sizeof(faddr);
174 			try (getsockname,
175 			      (ns, (struct sockaddr *)&faddr, &addrlen), "");
176 			dumpit("connected as:", &faddr, addrlen);
177 		}
178 		loop++;
179 		if(loop > 3) myexit(0);
180 		if (forkp) {
181 			try(fork, (), "");
182 		} else
183 			x = 0;
184 		if (x == 0)  {
185 		    long n, count = 0, cn, flags;
186 		    records = 0;
187 		    if (confp) {
188 			msghdr.msg_iovlen = 0;
189 			msghdr.msg_namelen = 0;
190 			msghdr.msg_controllen =
191 			    cbuf.cm.cmhdr.cmsg_len = sizeof (cbuf.cm.cmhdr);
192 			cbuf.cm.cmhdr.cmsg_level = SOL_TRANSPORT;
193 			cbuf.cm.cmhdr.cmsg_type = TPOPT_CFRM_DATA;
194 			n = sendmsg(ns, &msghdr, 0);
195 			if (n < 0) {
196 				printf("confirm: errno is %d\n", errno);
197 				fflush(stdout);
198 				perror("Confirm error");
199 			} else {
200 				dbprintf("confim ok\n");
201 			}
202 			sleep(3);
203 		    }
204 #ifdef ISODE_MODE
205 		    if (isode_mode) {
206 			static char fdbuf[10];
207 			static char *nargv[4] =
208 			    {"/usr/sbin/isod.tsap", fdbuf, "", 0};
209 			sprintf(fdbuf, "Z%d", ns);
210 			old_isod_main(3, nargv, xenvp);
211 			myexit(0);
212 		    }
213 #endif
214 		    for (;;) {
215 		    dgram1:
216 			msghdr.msg_iovlen = 1;
217 			msghdr.msg_controllen = sizeof(control);
218 			msghdr.msg_namelen = (dgramp ? (sizeof name) : 0);
219 			iov->iov_len = sizeof(readbuf);
220 			if (select_mode)
221 			    sel_recvwait(ns);
222 			n = recvmsg(ns, &msghdr, 0);
223 			flags = msghdr.msg_flags;
224 			count++;
225 			dbprintf("recvmsg from child %d got %d ctl %d flags %x\n",
226 				getpid(), n, (cn = msghdr.msg_controllen), flags);
227 			fflush(stdout);
228 			if (dgramp && msghdr.msg_namelen && verbose)
229 				dumpit("from:\n", name, msghdr.msg_namelen);
230 			if (cn && verbose)
231 				dumpit("control data:\n", control, cn);
232 			if (n < 0) {
233 				fprintf(stderr, "errno is %d\n", errno);
234 				perror("recvmsg");
235 				/*sleep (10);*/
236 				break;
237 			} else {
238 				if (verbose)
239 					dumpit("data:\n", readbuf, n);
240 			}
241 			if (echop)
242 				savedata(n, flags);
243 			if (flags & MSG_EOR) {
244 				records++;
245 				if (echop)
246 					answerback(ns);
247 			}
248 			errno = 0;
249 		    }
250 		    myexit(0);
251 		}
252 	}
253 }
254 struct savebuf {
255 	struct savebuf *s_next;
256 	struct savebuf *s_prev;
257 	int	s_n;
258 	int	s_flags;
259 } savebuf = {&savebuf, &savebuf};
260 
261 void
262 savedata(n, flags)
263 int n, flags;
264 {
265 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
266 	if (s == 0)
267 		return;
268 	insque(s, savebuf.s_prev);
269 	s->s_n = n;
270 	s->s_flags = flags;
271 	bcopy(readbuf, (char *)(s + 1), n);
272 }
273 
274 answerback(ns)
275 {
276 	int n;
277 	register struct savebuf *s = savebuf.s_next, *t;
278 	static struct iovec iov[1];
279 	static struct msghdr msghdr = { 0, 0, iov, 1, 0, 0, 0};
280 	while (s != &savebuf) {
281 		iov->iov_len = s->s_n;
282 		iov->iov_base = (char *)(s + 1);
283 		n = sendmsg(ns, &msghdr, s->s_flags);
284 		dbprintf("echoed %d\n", n);
285 		t = s; s = s->s_next; remque(t); free((char *)t);
286 	}
287 }
288 
289 dumpit(what, where, n)
290 char *what; unsigned short *where; int n;
291 {
292 	unsigned short *s = where;
293 	unsigned short *z = where + (n+1)/2;
294 	int count = 0;
295 	if (dumpnodata)
296 		return;
297 	printf(what);
298 	while(s < z) {
299 		count++;
300 		printf("%x ",*s++);
301 		if ((count & 15) == 0)
302 			putchar('\n');
303 	}
304 	if (count & 15)
305 		putchar('\n');
306 	fflush(stdout);
307 }
308 myexit(n)
309 {
310 	fflush(stderr);
311 	printf("got %d records\n", records);
312 	fflush(stdout);
313 	exit(n);
314 }
315 
316 sel_recvwait(fd)
317 int fd;
318 {
319 	int x;
320 	do {
321 		FD_ZERO(&readfds);
322 		FD_ZERO(&exceptfds);
323 		FD_SET(fd, &readfds);
324 		FD_SET(fd, &exceptfds);
325 		x = select(fd+1, &readfds, (fd_set *)0, &exceptfds, (void *)0);
326 		dbprintf("select returns %d\n", x);
327 	} while (x <= 0 ||
328 		 (FD_ISSET(fd,&readfds) == 0 && FD_ISSET(fd,&exceptfds) == 0));
329 }
330 
331 #include <sys/syscall.h>
332 /* Here for gdb trapping */
333 setsockopt(s, level, optname, optval, optlen)
334 int s, level, optname, optlen;
335 const void *optval;
336 {
337 
338 	dbprintf("setsocket called s %d, level 0x%x, optname %d, optlen %d\n",
339 			s, level, optname, optlen);
340 	dumpit("", optval, optlen);
341 	return syscall(SYS_setsockopt, s, level, optname, optval, optlen);
342 }
343