149352Sbostic /*- 249352Sbostic * Copyright (c) 1988, 1990 The Regents of the University of California. 344323Ssklower * All rights reserved. 444323Ssklower * 544323Ssklower * %sccs.include.redist.c% 644323Ssklower */ 749352Sbostic 844323Ssklower #ifndef lint 949352Sbostic char copyright[] = 1049352Sbostic "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\ 1149352Sbostic All rights reserved.\n"; 1244323Ssklower #endif /* not lint */ 1344323Ssklower 1449352Sbostic #ifndef lint 15*50515Ssklower static char sccsid[] = "@(#)tisink.c 7.7 (Berkeley) 07/24/91"; 1649352Sbostic #endif /* not lint */ 1749352Sbostic 1844323Ssklower /* 1948712Ssklower * This is a test program to be a sink for ISO packets. 2044323Ssklower */ 2144323Ssklower #include <sys/param.h> 2244323Ssklower #include <sys/uio.h> 2344323Ssklower #include <sys/socket.h> 2444323Ssklower #include <sys/ioctl.h> 2544323Ssklower #include <net/route.h> 2644323Ssklower #include <net/if.h> 2744323Ssklower #define TCPT_NTIMERS 4 2844323Ssklower #include <netiso/iso.h> 2944323Ssklower #include <netiso/tp_param.h> 3044323Ssklower #include <netiso/tp_user.h> 3144323Ssklower 3244323Ssklower #include <stdio.h> 3344323Ssklower #include <errno.h> 3444323Ssklower #include <ctype.h> 3544323Ssklower #include <netdb.h> 3644323Ssklower 3744323Ssklower 3844323Ssklower #define dbprintf if(verbose)printf 3944323Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\ 4044323Ssklower if(x<0) {perror("a"); myexit(0);}} 4144323Ssklower 4244323Ssklower 4344323Ssklower struct ifreq ifr; 4444323Ssklower short port = 3000; 4544323Ssklower struct sockaddr_iso faddr, laddr = { sizeof(laddr), AF_ISO }; 4644323Ssklower struct sockaddr_iso *siso = &laddr; 4748711Ssklower char **xenvp; 4844323Ssklower 49*50515Ssklower long size, count = 10, forkp, confp, mynamep, verbose = 1, playtag, echop = 1; 50*50515Ssklower long records, intercept = 0, isode_mode = 0, dgramp = 0, tp0mode = 0; 51*50515Ssklower void savedata(); 5244323Ssklower 5344323Ssklower char buf[2048]; 5444323Ssklower char your_it[] = "You're it!"; 5544323Ssklower 5644323Ssklower char *Servername; 5744323Ssklower 5848711Ssklower main(argc, argv, envp) 5944323Ssklower int argc; 6044323Ssklower char *argv[]; 6148711Ssklower char *envp[]; 6244323Ssklower { 6344323Ssklower register char **av = argv; 6444323Ssklower register char *cp; 6548712Ssklower struct iso_addr *iso_addr(); 6644323Ssklower 6748711Ssklower xenvp = envp; 6844323Ssklower while(--argc > 0) { 6944323Ssklower av++; 7044323Ssklower if(strcmp(*av,"Servername")==0) { 7144323Ssklower av++; 7244323Ssklower Servername = *av; 7344323Ssklower argc--; 7444323Ssklower } else if (strcmp(*av,"host")==0) { 7544323Ssklower av++; 7648712Ssklower laddr.siso_addr = *iso_addr(*av); 7744323Ssklower argc--; 7844323Ssklower } else if (strcmp(*av,"count")==0) { 7944323Ssklower av++; 8044323Ssklower sscanf(*av,"%ld",&count); 8144323Ssklower argc--; 8244323Ssklower } else if (strcmp(*av,"port")==0) { 8344323Ssklower av++; 8444323Ssklower sscanf(*av,"%hd",&port); 8544323Ssklower argc--; 8644323Ssklower } else if (strcmp(*av,"size")==0) { 8744323Ssklower av++; 8844323Ssklower sscanf(*av,"%ld",&size); 8944323Ssklower argc--; 9044600Ssklower } else if (strcmp(*av, "intercept")==0) { 9144600Ssklower intercept++; 9244323Ssklower } 9344323Ssklower } 9444323Ssklower if (Servername) { 9544323Ssklower int tlen = laddr.siso_tlen = strlen(Servername); 9644323Ssklower int len = TSEL(siso) + tlen - (caddr_t) &siso; 9744323Ssklower if (len > sizeof(*siso)) { 9844323Ssklower siso = (struct sockaddr_iso *)malloc(len); 9944323Ssklower *siso = laddr; 10044323Ssklower siso->siso_len = len; 10144323Ssklower } 10244323Ssklower bcopy(Servername, TSEL(siso), tlen); 10344323Ssklower } else { 10444323Ssklower port = htons(port); 10544323Ssklower laddr.siso_tlen = sizeof(port); 10644323Ssklower bcopy((char *)&port, TSEL(siso), sizeof(port)); 10744323Ssklower } 10844323Ssklower tisink(); 10944323Ssklower } 11044323Ssklower #define BIG 2048 11144323Ssklower #define MIDLIN 512 11244323Ssklower char readbuf[BIG]; 11344323Ssklower struct iovec iov[1] = { 11444323Ssklower readbuf, 11544323Ssklower sizeof readbuf, 11644323Ssklower }; 11744323Ssklower char name[MIDLIN]; 11844323Ssklower union { 11944323Ssklower struct { 12044323Ssklower struct cmsghdr cmhdr; 12144323Ssklower char cmdata[128 - sizeof(struct cmsghdr)]; 12244323Ssklower } cm; 12344323Ssklower char data[128]; 12444323Ssklower } cbuf; 12544323Ssklower #define control cbuf.data 12644323Ssklower struct msghdr msghdr = { 12744323Ssklower name, sizeof(name), 12844323Ssklower iov, sizeof(iov)/sizeof(iov[1]), 12944323Ssklower control, sizeof control, 13044323Ssklower 0 /* flags */ 13144323Ssklower }; 13244323Ssklower 13344323Ssklower tisink() 13444323Ssklower { 13548712Ssklower int x, s, pid, on = 1, loop = 0, n, ns; 13644323Ssklower extern int errno; 13748712Ssklower int socktype = (dgramp ? SOCK_DGRAM : SOCK_SEQPACKET); 138*50515Ssklower int proto = (tp0mode ? ISOPROTO_TP0 : 0 ); 13948712Ssklower int addrlen = sizeof(faddr); 14044323Ssklower 141*50515Ssklower try(socket, (AF_ISO, socktype, proto),""); 14244323Ssklower 14344323Ssklower s = x; 14444323Ssklower 14544323Ssklower try(bind, (s, (struct sockaddr *) siso, siso->siso_len), ""); 14644323Ssklower 14744323Ssklower /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */ 14848712Ssklower if (dgramp) { 14948712Ssklower ns = s; 15048712Ssklower goto dgram1; 15148712Ssklower } 15244323Ssklower 15344323Ssklower try(listen, (s, 5), ""); 15444424Ssklower if (intercept) { 15544424Ssklower try(setsockopt, 15644424Ssklower (s, SOL_TRANSPORT, TPOPT_INTERCEPT, &on, sizeof(on)), ""); 15744424Ssklower } 15844323Ssklower for(;;) { 15948712Ssklower int child; 16044323Ssklower char childname[50]; 16144323Ssklower 162*50515Ssklower try (accept, (s, (struct sockaddr *)&faddr, &addrlen), ""); 16344323Ssklower ns = x; 16444323Ssklower dumpit("connection from:", &faddr, sizeof faddr); 16544600Ssklower if (mynamep || intercept) { 16644323Ssklower addrlen = sizeof(faddr); 167*50515Ssklower try (getsockname, 168*50515Ssklower (ns, (struct sockaddr *)&faddr, &addrlen), ""); 16944323Ssklower dumpit("connected as:", &faddr, addrlen); 17044323Ssklower } 17144323Ssklower loop++; 17248712Ssklower if(loop > 3) myexit(0); 17344323Ssklower if (forkp) { 17444323Ssklower try(fork, (), ""); 17544323Ssklower } else 17644323Ssklower x = 0; 17744323Ssklower if (x == 0) { 17844323Ssklower long n, count = 0, cn, flags; 17944323Ssklower records = 0; 18044323Ssklower if (confp) { 18144323Ssklower msghdr.msg_iovlen = 0; 18244323Ssklower msghdr.msg_namelen = 0; 18344323Ssklower msghdr.msg_controllen = 18444323Ssklower cbuf.cm.cmhdr.cmsg_len = sizeof (cbuf.cm.cmhdr); 18544323Ssklower cbuf.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 18644323Ssklower cbuf.cm.cmhdr.cmsg_type = TPOPT_CFRM_DATA; 18744323Ssklower n = sendmsg(ns, &msghdr, 0); 18848712Ssklower if (n < 0) { 18944323Ssklower printf("confirm: errno is %d\n", errno); 19044323Ssklower fflush(stdout); 19144323Ssklower perror("Confirm error"); 19244323Ssklower } else { 19344323Ssklower dbprintf("confim ok\n"); 19444323Ssklower } 19544323Ssklower sleep(10); 19644323Ssklower } 19748711Ssklower #ifdef ISODE_MODE 19848711Ssklower if (isode_mode) { 19948711Ssklower static char fdbuf[10]; 20048711Ssklower static char *nargv[4] = 20148711Ssklower {"/usr/sbin/isod.tsap", fdbuf, "", 0}; 20248711Ssklower sprintf(fdbuf, "Z%d", ns); 20348711Ssklower old_isod_main(3, nargv, xenvp); 20448711Ssklower } else 20548711Ssklower #endif 20644323Ssklower for (;;) { 20748712Ssklower dgram1: 20844323Ssklower msghdr.msg_iovlen = 1; 20944323Ssklower msghdr.msg_controllen = sizeof(control); 21048712Ssklower msghdr.msg_namelen = (dgramp ? (sizeof name) : 0); 21144323Ssklower iov->iov_len = sizeof(readbuf); 21244323Ssklower n = recvmsg(ns, &msghdr, 0); 21344323Ssklower flags = msghdr.msg_flags; 21444323Ssklower count++; 21544323Ssklower dbprintf("recvmsg from child %d got %d ctl %d flags %x\n", 21648712Ssklower getpid(), n, (cn = msghdr.msg_controllen), flags); 21744323Ssklower fflush(stdout); 21848712Ssklower if (dgramp && msghdr.msg_namelen && verbose) 21948712Ssklower dumpit("from:\n", name, msghdr.msg_namelen); 22044323Ssklower if (cn && verbose) 22144323Ssklower dumpit("control data:\n", control, cn); 22244323Ssklower if (n < 0) { 22344323Ssklower fprintf(stderr, "errno is %d\n", errno); 22444323Ssklower perror("recvmsg"); 22544323Ssklower /*sleep (10);*/ 22644323Ssklower break; 22744323Ssklower } else { 22844323Ssklower if (verbose) 22944323Ssklower dumpit("data:\n", readbuf, n); 23044323Ssklower } 231*50515Ssklower if (echop) 232*50515Ssklower savedata(n, flags); 233*50515Ssklower if (flags & MSG_EOR) { 23444323Ssklower records++; 235*50515Ssklower if (echop) 236*50515Ssklower answerback(ns); 23744323Ssklower } 23844323Ssklower errno = 0; 23944323Ssklower } 24044323Ssklower } 24144323Ssklower myexit(0); 24244323Ssklower } 24344323Ssklower } 244*50515Ssklower struct savebuf { 245*50515Ssklower struct savebuf *s_next; 246*50515Ssklower struct savebuf *s_prev; 247*50515Ssklower int s_n; 248*50515Ssklower int s_flags; 249*50515Ssklower } savebuf = {&savebuf, &savebuf}; 250*50515Ssklower 251*50515Ssklower void 252*50515Ssklower savedata(n, flags) 253*50515Ssklower int n, flags; 25444323Ssklower { 255*50515Ssklower register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s); 256*50515Ssklower if (s == 0) 257*50515Ssklower return; 258*50515Ssklower insque(s, savebuf.s_prev); 259*50515Ssklower s->s_n = n; 260*50515Ssklower s->s_flags = flags; 261*50515Ssklower bcopy(readbuf, (char *)(s + 1), n); 26244323Ssklower } 26344323Ssklower 264*50515Ssklower answerback(ns) 265*50515Ssklower { 266*50515Ssklower int n; 267*50515Ssklower register struct savebuf *s = savebuf.s_next, *t; 268*50515Ssklower static struct iovec iov[1]; 269*50515Ssklower static struct msghdr msghdr = { 0, 0, iov, 1, 0, 0, 0}; 270*50515Ssklower while (s != &savebuf) { 271*50515Ssklower iov->iov_len = s->s_n; 272*50515Ssklower iov->iov_base = (char *)(s + 1); 273*50515Ssklower n = sendmsg(ns, &msghdr, s->s_flags); 274*50515Ssklower dbprintf("echoed %d\n", n); 275*50515Ssklower t = s; s = s->s_next; remque(t); free((char *)t); 276*50515Ssklower } 277*50515Ssklower } 278*50515Ssklower 27944323Ssklower dumpit(what, where, n) 28044323Ssklower char *what; unsigned short *where; int n; 28144323Ssklower { 28244323Ssklower unsigned short *s = where; 28344323Ssklower unsigned short *z = where + (n+1)/2; 28444323Ssklower int count = 0; 28544323Ssklower printf(what); 28644323Ssklower while(s < z) { 28744323Ssklower count++; 28844323Ssklower printf("%x ",*s++); 28944323Ssklower if ((count & 15) == 0) 29044323Ssklower putchar('\n'); 29144323Ssklower } 29244323Ssklower if (count & 15) 29344323Ssklower putchar('\n'); 29444323Ssklower fflush(stdout); 29544323Ssklower } 29644323Ssklower myexit(n) 29744323Ssklower { 29844323Ssklower fflush(stderr); 29944323Ssklower printf("got %d records\n", records); 30044323Ssklower fflush(stdout); 30144323Ssklower exit(n); 30244323Ssklower } 303