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
main(argc,argv,envp)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
xisink()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
savedata(n)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
answerback(ns)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
dumpit(what,where,n)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 }
myexit(n)236 myexit(n)
237 {
238 fflush(stderr);
239 printf("got %d records\n", records);
240 fflush(stdout);
241 exit(n);
242 }
243