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