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*50890Ssklower static char sccsid[] = "@(#)tisink.c 7.9 (Berkeley) 08/22/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 39*50890Ssklower #ifdef __STDC__ 40*50890Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\ 41*50890Ssklower if (x<0) {perror(#a); myexit(0);}} 42*50890Ssklower #else 4344323Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\ 44*50890Ssklower if (x<0) {perror("a"); myexit(0);}} 45*50890Ssklower #endif 4644323Ssklower 4744323Ssklower 4844323Ssklower struct ifreq ifr; 4944323Ssklower short port = 3000; 5044323Ssklower struct sockaddr_iso faddr, laddr = { sizeof(laddr), AF_ISO }; 5144323Ssklower struct sockaddr_iso *siso = &laddr; 5248711Ssklower char **xenvp; 5344323Ssklower 54*50890Ssklower long size, forkp = 0, confp, mynamep, verbose = 1, echop = 0; 5550515Ssklower long records, intercept = 0, isode_mode = 0, dgramp = 0, tp0mode = 0; 56*50890Ssklower long dumpnodata = 0, playtag = 0; 5750515Ssklower void savedata(); 5844323Ssklower 5944323Ssklower char buf[2048]; 6044323Ssklower char your_it[] = "You're it!"; 6144323Ssklower 6244323Ssklower char *Servername; 6344323Ssklower 6448711Ssklower main(argc, argv, envp) 6544323Ssklower int argc; 6644323Ssklower char *argv[]; 6748711Ssklower char *envp[]; 6844323Ssklower { 6944323Ssklower register char **av = argv; 7044323Ssklower register char *cp; 7148712Ssklower struct iso_addr *iso_addr(); 7244323Ssklower 7348711Ssklower xenvp = envp; 7444323Ssklower while(--argc > 0) { 7544323Ssklower av++; 7644323Ssklower if(strcmp(*av,"Servername")==0) { 7744323Ssklower av++; 7844323Ssklower Servername = *av; 7944323Ssklower argc--; 8044323Ssklower } else if (strcmp(*av,"host")==0) { 8144323Ssklower av++; 8248712Ssklower laddr.siso_addr = *iso_addr(*av); 8344323Ssklower argc--; 8444323Ssklower } else if (strcmp(*av,"port")==0) { 8544323Ssklower av++; 8644323Ssklower sscanf(*av,"%hd",&port); 8744323Ssklower argc--; 8844323Ssklower } else if (strcmp(*av,"size")==0) { 8944323Ssklower av++; 9044323Ssklower sscanf(*av,"%ld",&size); 9144323Ssklower argc--; 92*50890Ssklower } else if (strcmp(*av, "echo")==0) { 93*50890Ssklower echop++; 9444600Ssklower } else if (strcmp(*av, "intercept")==0) { 9544600Ssklower intercept++; 9644323Ssklower } 9744323Ssklower } 9844323Ssklower if (Servername) { 9944323Ssklower int tlen = laddr.siso_tlen = strlen(Servername); 10044323Ssklower int len = TSEL(siso) + tlen - (caddr_t) &siso; 10144323Ssklower if (len > sizeof(*siso)) { 10244323Ssklower siso = (struct sockaddr_iso *)malloc(len); 10344323Ssklower *siso = laddr; 10444323Ssklower siso->siso_len = len; 10544323Ssklower } 10644323Ssklower bcopy(Servername, TSEL(siso), tlen); 10744323Ssklower } else { 10844323Ssklower port = htons(port); 10944323Ssklower laddr.siso_tlen = sizeof(port); 11044323Ssklower bcopy((char *)&port, TSEL(siso), sizeof(port)); 11144323Ssklower } 11244323Ssklower tisink(); 11344323Ssklower } 11444323Ssklower #define BIG 2048 11544323Ssklower #define MIDLIN 512 11644323Ssklower char readbuf[BIG]; 11744323Ssklower struct iovec iov[1] = { 11844323Ssklower readbuf, 11944323Ssklower sizeof readbuf, 12044323Ssklower }; 12144323Ssklower char name[MIDLIN]; 12244323Ssklower union { 12344323Ssklower struct { 12444323Ssklower struct cmsghdr cmhdr; 12544323Ssklower char cmdata[128 - sizeof(struct cmsghdr)]; 12644323Ssklower } cm; 12744323Ssklower char data[128]; 12844323Ssklower } cbuf; 12944323Ssklower #define control cbuf.data 13044323Ssklower struct msghdr msghdr = { 13144323Ssklower name, sizeof(name), 13244323Ssklower iov, sizeof(iov)/sizeof(iov[1]), 13344323Ssklower control, sizeof control, 13444323Ssklower 0 /* flags */ 13544323Ssklower }; 13644323Ssklower 13744323Ssklower tisink() 13844323Ssklower { 13948712Ssklower int x, s, pid, on = 1, loop = 0, n, ns; 14044323Ssklower extern int errno; 14148712Ssklower int socktype = (dgramp ? SOCK_DGRAM : SOCK_SEQPACKET); 14250515Ssklower int proto = (tp0mode ? ISOPROTO_TP0 : 0 ); 14348712Ssklower int addrlen = sizeof(faddr); 14444323Ssklower 14550515Ssklower try(socket, (AF_ISO, socktype, proto),""); 14644323Ssklower 14744323Ssklower s = x; 14844323Ssklower 14944323Ssklower try(bind, (s, (struct sockaddr *) siso, siso->siso_len), ""); 15044323Ssklower 15144323Ssklower /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */ 15248712Ssklower if (dgramp) { 15348712Ssklower ns = s; 15448712Ssklower goto dgram1; 15548712Ssklower } 15644323Ssklower 15744323Ssklower try(listen, (s, 5), ""); 15844424Ssklower if (intercept) { 15944424Ssklower try(setsockopt, 16044424Ssklower (s, SOL_TRANSPORT, TPOPT_INTERCEPT, &on, sizeof(on)), ""); 16144424Ssklower } 16244323Ssklower for(;;) { 16348712Ssklower int child; 16444323Ssklower char childname[50]; 16544323Ssklower 16650515Ssklower try (accept, (s, (struct sockaddr *)&faddr, &addrlen), ""); 16744323Ssklower ns = x; 16844323Ssklower dumpit("connection from:", &faddr, sizeof faddr); 16944600Ssklower if (mynamep || intercept) { 17044323Ssklower addrlen = sizeof(faddr); 17150515Ssklower try (getsockname, 17250515Ssklower (ns, (struct sockaddr *)&faddr, &addrlen), ""); 17344323Ssklower dumpit("connected as:", &faddr, addrlen); 17444323Ssklower } 17544323Ssklower loop++; 17648712Ssklower if(loop > 3) myexit(0); 17744323Ssklower if (forkp) { 17844323Ssklower try(fork, (), ""); 17944323Ssklower } else 18044323Ssklower x = 0; 18144323Ssklower if (x == 0) { 18244323Ssklower long n, count = 0, cn, flags; 18344323Ssklower records = 0; 18444323Ssklower if (confp) { 18544323Ssklower msghdr.msg_iovlen = 0; 18644323Ssklower msghdr.msg_namelen = 0; 18744323Ssklower msghdr.msg_controllen = 18844323Ssklower cbuf.cm.cmhdr.cmsg_len = sizeof (cbuf.cm.cmhdr); 18944323Ssklower cbuf.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 19044323Ssklower cbuf.cm.cmhdr.cmsg_type = TPOPT_CFRM_DATA; 19144323Ssklower n = sendmsg(ns, &msghdr, 0); 19248712Ssklower if (n < 0) { 19344323Ssklower printf("confirm: errno is %d\n", errno); 19444323Ssklower fflush(stdout); 19544323Ssklower perror("Confirm error"); 19644323Ssklower } else { 19744323Ssklower dbprintf("confim ok\n"); 19844323Ssklower } 19944323Ssklower sleep(10); 20044323Ssklower } 20148711Ssklower #ifdef ISODE_MODE 20248711Ssklower if (isode_mode) { 20348711Ssklower static char fdbuf[10]; 20448711Ssklower static char *nargv[4] = 20548711Ssklower {"/usr/sbin/isod.tsap", fdbuf, "", 0}; 20648711Ssklower sprintf(fdbuf, "Z%d", ns); 20748711Ssklower old_isod_main(3, nargv, xenvp); 20848711Ssklower } else 20948711Ssklower #endif 21044323Ssklower for (;;) { 21148712Ssklower dgram1: 21244323Ssklower msghdr.msg_iovlen = 1; 21344323Ssklower msghdr.msg_controllen = sizeof(control); 21448712Ssklower msghdr.msg_namelen = (dgramp ? (sizeof name) : 0); 21544323Ssklower iov->iov_len = sizeof(readbuf); 21644323Ssklower n = recvmsg(ns, &msghdr, 0); 21744323Ssklower flags = msghdr.msg_flags; 21844323Ssklower count++; 21944323Ssklower dbprintf("recvmsg from child %d got %d ctl %d flags %x\n", 22048712Ssklower getpid(), n, (cn = msghdr.msg_controllen), flags); 22144323Ssklower fflush(stdout); 22248712Ssklower if (dgramp && msghdr.msg_namelen && verbose) 22348712Ssklower dumpit("from:\n", name, msghdr.msg_namelen); 22444323Ssklower if (cn && verbose) 22544323Ssklower dumpit("control data:\n", control, cn); 22644323Ssklower if (n < 0) { 22744323Ssklower fprintf(stderr, "errno is %d\n", errno); 22844323Ssklower perror("recvmsg"); 22944323Ssklower /*sleep (10);*/ 23044323Ssklower break; 23144323Ssklower } else { 23244323Ssklower if (verbose) 23344323Ssklower dumpit("data:\n", readbuf, n); 23444323Ssklower } 23550515Ssklower if (echop) 23650515Ssklower savedata(n, flags); 23750515Ssklower if (flags & MSG_EOR) { 23844323Ssklower records++; 23950515Ssklower if (echop) 24050515Ssklower answerback(ns); 24144323Ssklower } 24244323Ssklower errno = 0; 24344323Ssklower } 244*50890Ssklower myexit(0); 24544323Ssklower } 24644323Ssklower } 24744323Ssklower } 24850515Ssklower struct savebuf { 24950515Ssklower struct savebuf *s_next; 25050515Ssklower struct savebuf *s_prev; 25150515Ssklower int s_n; 25250515Ssklower int s_flags; 25350515Ssklower } savebuf = {&savebuf, &savebuf}; 25450515Ssklower 25550515Ssklower void 25650515Ssklower savedata(n, flags) 25750515Ssklower int n, flags; 25844323Ssklower { 25950515Ssklower register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s); 26050515Ssklower if (s == 0) 26150515Ssklower return; 26250515Ssklower insque(s, savebuf.s_prev); 26350515Ssklower s->s_n = n; 26450515Ssklower s->s_flags = flags; 26550515Ssklower bcopy(readbuf, (char *)(s + 1), n); 26644323Ssklower } 26744323Ssklower 26850515Ssklower answerback(ns) 26950515Ssklower { 27050515Ssklower int n; 27150515Ssklower register struct savebuf *s = savebuf.s_next, *t; 27250515Ssklower static struct iovec iov[1]; 27350515Ssklower static struct msghdr msghdr = { 0, 0, iov, 1, 0, 0, 0}; 27450515Ssklower while (s != &savebuf) { 27550515Ssklower iov->iov_len = s->s_n; 27650515Ssklower iov->iov_base = (char *)(s + 1); 27750515Ssklower n = sendmsg(ns, &msghdr, s->s_flags); 27850515Ssklower dbprintf("echoed %d\n", n); 27950515Ssklower t = s; s = s->s_next; remque(t); free((char *)t); 28050515Ssklower } 28150515Ssklower } 28250515Ssklower 28344323Ssklower dumpit(what, where, n) 28444323Ssklower char *what; unsigned short *where; int n; 28544323Ssklower { 28644323Ssklower unsigned short *s = where; 28744323Ssklower unsigned short *z = where + (n+1)/2; 28844323Ssklower int count = 0; 289*50890Ssklower if (dumpnodata) 290*50890Ssklower return; 29144323Ssklower printf(what); 29244323Ssklower while(s < z) { 29344323Ssklower count++; 29444323Ssklower printf("%x ",*s++); 29544323Ssklower if ((count & 15) == 0) 29644323Ssklower putchar('\n'); 29744323Ssklower } 29844323Ssklower if (count & 15) 29944323Ssklower putchar('\n'); 30044323Ssklower fflush(stdout); 30144323Ssklower } 30244323Ssklower myexit(n) 30344323Ssklower { 30444323Ssklower fflush(stderr); 30544323Ssklower printf("got %d records\n", records); 30644323Ssklower fflush(stdout); 30744323Ssklower exit(n); 30844323Ssklower } 309