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