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