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