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