xref: /original-bsd/sys/tests/netccitt/xi_sink.c (revision 42c7e7a1)
1 /*-
2  * Copyright (c) 1988, 1991 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, 1991 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[] = "@(#)xi_sink.c	7.6 (Berkeley) 07/15/91";
16 #endif /* not lint */
17 
18 /*
19  * This is a test program to be a sink for X.25 connections.
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 #include <netccitt/x25.h>
28 
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include <netdb.h>
33 
34 
35 #define dbprintf if(verbose)printf
36 #ifdef __STDC__
37 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
38 		if(x<0) {perror(#a); myexit(0);}}
39 #else
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 #endif
43 
44 
45 struct  ifreq ifr;
46 short port = 3000;
47 struct  sockaddr_x25 faddr, laddr = { sizeof(laddr), AF_CCITT };
48 struct  sockaddr_x25 *sx25 = &laddr;
49 char **xenvp;
50 
51 long size, count = 10, forkp, echop = 0, mynamep, verbose = 1, playtag = 0;
52 long records, intercept = 0, confp;
53 void savedata();
54 
55 char buf[2048];
56 char your_it[] = "You're it!";
57 
58 char *Servername;
59 
60 main(argc, argv, envp)
61 int argc;
62 char *argv[];
63 char *envp[];
64 {
65 	register char **av = argv;
66 	register char *cp;
67 
68 	xenvp = envp;
69 	while(--argc > 0) {
70 		av++;
71 		if (strcmp(*av,"host")==0) {
72 			av++;
73 			ccitt_addr(*av, sx25);
74 			argc--;
75 		} else if (strcmp(*av,"count")==0) {
76 			av++;
77 			sscanf(*av,"%ld",&count);
78 			argc--;
79 		} else if (strcmp(*av,"size")==0) {
80 			av++;
81 			sscanf(*av,"%ld",&size);
82 			argc--;
83 		} else if (strcmp(*av, "intercept")==0) {
84 			intercept++;
85 		}
86 	}
87 	xisink();
88 }
89 #define BIG 2048
90 #define MIDLIN 512
91 char readbuf[BIG];
92 char name[MIDLIN];
93 struct iovec iov[1];
94 union {
95     struct {
96 	    struct cmsghdr	cmhdr;
97 	    char		cmdata[128 - sizeof(struct cmsghdr)];
98     } cm;
99     char data[128];
100 } cbuf;
101 #define control cbuf.data
102 struct msghdr msghdr = {
103 	0, 0,
104 	iov, sizeof(iov)/sizeof(iov[1]),
105 	0, 0, 0
106 };
107 
108 xisink()
109 {
110 	int x, s, pid, on = 1, loop = 0, n;
111 	extern int errno;
112 
113 	try(socket, (AF_CCITT, SOCK_STREAM, 0),"");
114 
115 	s = x;
116 
117 	sx25->x25_opts.op_flags |= X25_MQBIT;
118 	try(bind, (s, (struct sockaddr *) sx25, sx25->x25_len), "");
119 
120 	/*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */
121 
122 	try(listen, (s, 5), "");
123 	for(;;) {
124 		int child, ns;
125 		int addrlen = sizeof(faddr);
126 		char childname[50];
127 
128 		try (accept, (s, (struct sockaddr *)&faddr, &addrlen), "");
129 		ns = x;
130 		dumpit("connection from:", &faddr, sizeof faddr);
131 		if (mynamep || intercept) {
132 			addrlen = sizeof(faddr);
133 			try (getsockname, (ns, (struct sockaddr *)&faddr,
134 				&addrlen), "");
135 			dumpit("connected as:", &faddr, addrlen);
136 		}
137 		loop++;
138 		if (loop > 3) myexit(0);
139 		if (forkp) {
140 			try(fork, (), "");
141 		} else
142 			x = 0;
143 		if (x == 0)  {
144 		    long n, count = 0, cn, flags;
145 		    records = 0;
146 		    for (;;) {
147 			msghdr.msg_controllen = sizeof(control);
148 			msghdr.msg_control = control;
149 			iov->iov_len = sizeof(readbuf);
150 			iov->iov_base = readbuf;
151 			n = recvmsg(ns, &msghdr, 0);
152 			flags = msghdr.msg_flags;
153 			count++;
154 			dbprintf("recvmsg from child %d got %d ctl %d flags %x\n",
155 				    getpid(), n, (cn = msghdr.msg_controllen),
156 					flags);
157 			fflush(stdout);
158 			if (cn && verbose)
159 				dumpit("control data:\n", control, cn);
160 			if (n < 0) {
161 				fprintf(stderr, "errno is %d\n", errno);
162 				perror("recvmsg");
163 				/*sleep (10);*/
164 				break;
165 			} else {
166 				if (verbose)
167 					dumpit("data:\n", readbuf, n);
168 			}
169 			if (echop)
170 				savedata(n);
171 			if (flags & MSG_EOR)
172 				records++;
173 			if (echop && (readbuf[0] & 0x80)) {
174 				dbprintf("Answering back!!!!\n");
175 				answerback(ns);
176 			}
177 			errno = 0;
178 		    }
179 		}
180 		myexit(0);
181 	}
182 }
183 
184 struct savebuf {
185 	struct savebuf *s_next;
186 	struct savebuf *s_prev;
187 	int	s_n;
188 	int	s_flags;
189 } savebuf = {&savebuf, &savebuf};
190 
191 void
192 savedata(n)
193 int n;
194 {
195 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
196 	if (s == 0)
197 		return;
198 	insque(s, savebuf.s_prev);
199 	s->s_n = n;
200 	s->s_flags = msghdr.msg_flags;
201 	bcopy(readbuf, (char *)(s + 1), n);
202 }
203 
204 answerback(ns)
205 {
206 	int n;
207 	register struct savebuf *s = savebuf.s_next, *t;
208 	msghdr.msg_controllen = 0;
209 	msghdr.msg_control = 0;
210 	while (s != &savebuf) {
211 		iov->iov_len = s->s_n;
212 		iov->iov_base = (char *)(s + 1);
213 		n = sendmsg(ns, &msghdr, s->s_flags);
214 		dbprintf("echoed %d\n", n);
215 		t = s; s = s->s_next; remque(t); free((char *)t);
216 	}
217 }
218 
219 dumpit(what, where, n)
220 char *what; unsigned short *where; int n;
221 {
222 	unsigned short *s = where;
223 	unsigned short *z = where + (n+1)/2;
224 	int count = 0;
225 	printf(what);
226 	while(s < z) {
227 		count++;
228 		printf("%x ",*s++);
229 		if ((count & 15) == 0)
230 			putchar('\n');
231 	}
232 	if (count & 15)
233 		putchar('\n');
234 	fflush(stdout);
235 }
236 myexit(n)
237 {
238 	fflush(stderr);
239 	printf("got %d records\n", records);
240 	fflush(stdout);
241 	exit(n);
242 }
243