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*55605Ssklower static char sccsid[] = "@(#)tisink.c 7.10 (Berkeley) 07/23/92"; 1649352Sbostic #endif /* not lint */ 1749352Sbostic 1844323Ssklower /* 1948712Ssklower * This is a test program to be a sink for ISO packets. 2044323Ssklower */ 21*55605Ssklower #include <unistd.h> 2244323Ssklower #include <sys/param.h> 2344323Ssklower #include <sys/uio.h> 2444323Ssklower #include <sys/socket.h> 2544323Ssklower #include <sys/ioctl.h> 26*55605Ssklower #include <sys/syscall.h> 2744323Ssklower #include <net/route.h> 2844323Ssklower #include <net/if.h> 2944323Ssklower #define TCPT_NTIMERS 4 3044323Ssklower #include <netiso/iso.h> 3144323Ssklower #include <netiso/tp_param.h> 3244323Ssklower #include <netiso/tp_user.h> 3344323Ssklower 3444323Ssklower #include <stdio.h> 3544323Ssklower #include <errno.h> 3644323Ssklower #include <ctype.h> 3744323Ssklower #include <netdb.h> 3844323Ssklower 3944323Ssklower 4044323Ssklower #define dbprintf if(verbose)printf 4150890Ssklower #ifdef __STDC__ 4250890Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\ 4350890Ssklower if (x<0) {perror(#a); myexit(0);}} 4450890Ssklower #else 4544323Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\ 4650890Ssklower if (x<0) {perror("a"); myexit(0);}} 4750890Ssklower #endif 4844323Ssklower 4944323Ssklower 5044323Ssklower struct ifreq ifr; 5144323Ssklower short port = 3000; 5244323Ssklower struct sockaddr_iso faddr, laddr = { sizeof(laddr), AF_ISO }; 5344323Ssklower struct sockaddr_iso *siso = &laddr; 5448711Ssklower char **xenvp; 5544323Ssklower 56*55605Ssklower long size, forkp = 0, confp = 0, mynamep, verbose = 1, echop = 0; 5750515Ssklower long records, intercept = 0, isode_mode = 0, dgramp = 0, tp0mode = 0; 58*55605Ssklower long dumpnodata = 0, playtag = 0, select_mode = 0; 5950515Ssklower void savedata(); 6044323Ssklower 6144323Ssklower char buf[2048]; 6244323Ssklower char your_it[] = "You're it!"; 63*55605Ssklower fd_set readfds, exceptfds; 6444323Ssklower 6544323Ssklower char *Servername; 6644323Ssklower 6748711Ssklower main(argc, argv, envp) 6844323Ssklower int argc; 6944323Ssklower char *argv[]; 7048711Ssklower char *envp[]; 7144323Ssklower { 7244323Ssklower register char **av = argv; 7344323Ssklower register char *cp; 7448712Ssklower struct iso_addr *iso_addr(); 7544323Ssklower 7648711Ssklower xenvp = envp; 7744323Ssklower while(--argc > 0) { 7844323Ssklower av++; 7944323Ssklower if(strcmp(*av,"Servername")==0) { 8044323Ssklower av++; 8144323Ssklower Servername = *av; 8244323Ssklower argc--; 8344323Ssklower } else if (strcmp(*av,"host")==0) { 8444323Ssklower av++; 8548712Ssklower laddr.siso_addr = *iso_addr(*av); 8644323Ssklower argc--; 8744323Ssklower } else if (strcmp(*av,"port")==0) { 8844323Ssklower av++; 8944323Ssklower sscanf(*av,"%hd",&port); 9044323Ssklower argc--; 9144323Ssklower } else if (strcmp(*av,"size")==0) { 9244323Ssklower av++; 9344323Ssklower sscanf(*av,"%ld",&size); 9444323Ssklower argc--; 9550890Ssklower } else if (strcmp(*av, "echo")==0) { 9650890Ssklower echop++; 9744600Ssklower } else if (strcmp(*av, "intercept")==0) { 9844600Ssklower intercept++; 9944323Ssklower } 10044323Ssklower } 10144323Ssklower if (Servername) { 10244323Ssklower int tlen = laddr.siso_tlen = strlen(Servername); 10344323Ssklower int len = TSEL(siso) + tlen - (caddr_t) &siso; 10444323Ssklower if (len > sizeof(*siso)) { 10544323Ssklower siso = (struct sockaddr_iso *)malloc(len); 10644323Ssklower *siso = laddr; 10744323Ssklower siso->siso_len = len; 10844323Ssklower } 10944323Ssklower bcopy(Servername, TSEL(siso), tlen); 11044323Ssklower } else { 11144323Ssklower port = htons(port); 11244323Ssklower laddr.siso_tlen = sizeof(port); 11344323Ssklower bcopy((char *)&port, TSEL(siso), sizeof(port)); 11444323Ssklower } 11544323Ssklower tisink(); 11644323Ssklower } 11744323Ssklower #define BIG 2048 11844323Ssklower #define MIDLIN 512 11944323Ssklower char readbuf[BIG]; 12044323Ssklower struct iovec iov[1] = { 12144323Ssklower readbuf, 12244323Ssklower sizeof readbuf, 12344323Ssklower }; 12444323Ssklower char name[MIDLIN]; 12544323Ssklower union { 12644323Ssklower struct { 12744323Ssklower struct cmsghdr cmhdr; 12844323Ssklower char cmdata[128 - sizeof(struct cmsghdr)]; 12944323Ssklower } cm; 13044323Ssklower char data[128]; 13144323Ssklower } cbuf; 13244323Ssklower #define control cbuf.data 13344323Ssklower struct msghdr msghdr = { 13444323Ssklower name, sizeof(name), 13544323Ssklower iov, sizeof(iov)/sizeof(iov[1]), 13644323Ssklower control, sizeof control, 13744323Ssklower 0 /* flags */ 13844323Ssklower }; 13944323Ssklower 14044323Ssklower tisink() 14144323Ssklower { 14248712Ssklower int x, s, pid, on = 1, loop = 0, n, ns; 14344323Ssklower extern int errno; 14448712Ssklower int socktype = (dgramp ? SOCK_DGRAM : SOCK_SEQPACKET); 14550515Ssklower int proto = (tp0mode ? ISOPROTO_TP0 : 0 ); 14648712Ssklower int addrlen = sizeof(faddr); 14744323Ssklower 14850515Ssklower try(socket, (AF_ISO, socktype, proto),""); 14944323Ssklower 15044323Ssklower s = x; 15144323Ssklower 15244323Ssklower try(bind, (s, (struct sockaddr *) siso, siso->siso_len), ""); 15344323Ssklower 15444323Ssklower /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */ 15548712Ssklower if (dgramp) { 15648712Ssklower ns = s; 15748712Ssklower goto dgram1; 15848712Ssklower } 15944323Ssklower 16044323Ssklower try(listen, (s, 5), ""); 16144424Ssklower if (intercept) { 16244424Ssklower try(setsockopt, 16344424Ssklower (s, SOL_TRANSPORT, TPOPT_INTERCEPT, &on, sizeof(on)), ""); 16444424Ssklower } 16544323Ssklower for(;;) { 16648712Ssklower int child; 16744323Ssklower char childname[50]; 16844323Ssklower 16950515Ssklower try (accept, (s, (struct sockaddr *)&faddr, &addrlen), ""); 17044323Ssklower ns = x; 17144323Ssklower dumpit("connection from:", &faddr, sizeof faddr); 17244600Ssklower if (mynamep || intercept) { 17344323Ssklower addrlen = sizeof(faddr); 17450515Ssklower try (getsockname, 17550515Ssklower (ns, (struct sockaddr *)&faddr, &addrlen), ""); 17644323Ssklower dumpit("connected as:", &faddr, addrlen); 17744323Ssklower } 17844323Ssklower loop++; 17948712Ssklower if(loop > 3) myexit(0); 18044323Ssklower if (forkp) { 18144323Ssklower try(fork, (), ""); 18244323Ssklower } else 18344323Ssklower x = 0; 18444323Ssklower if (x == 0) { 18544323Ssklower long n, count = 0, cn, flags; 18644323Ssklower records = 0; 18744323Ssklower if (confp) { 18844323Ssklower msghdr.msg_iovlen = 0; 18944323Ssklower msghdr.msg_namelen = 0; 19044323Ssklower msghdr.msg_controllen = 19144323Ssklower cbuf.cm.cmhdr.cmsg_len = sizeof (cbuf.cm.cmhdr); 19244323Ssklower cbuf.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 19344323Ssklower cbuf.cm.cmhdr.cmsg_type = TPOPT_CFRM_DATA; 19444323Ssklower n = sendmsg(ns, &msghdr, 0); 19548712Ssklower if (n < 0) { 19644323Ssklower printf("confirm: errno is %d\n", errno); 19744323Ssklower fflush(stdout); 19844323Ssklower perror("Confirm error"); 19944323Ssklower } else { 20044323Ssklower dbprintf("confim ok\n"); 20144323Ssklower } 202*55605Ssklower sleep(3); 20344323Ssklower } 20448711Ssklower #ifdef ISODE_MODE 20548711Ssklower if (isode_mode) { 20648711Ssklower static char fdbuf[10]; 20748711Ssklower static char *nargv[4] = 20848711Ssklower {"/usr/sbin/isod.tsap", fdbuf, "", 0}; 20948711Ssklower sprintf(fdbuf, "Z%d", ns); 21048711Ssklower old_isod_main(3, nargv, xenvp); 211*55605Ssklower myexit(0); 212*55605Ssklower } 21348711Ssklower #endif 21444323Ssklower for (;;) { 21548712Ssklower dgram1: 21644323Ssklower msghdr.msg_iovlen = 1; 21744323Ssklower msghdr.msg_controllen = sizeof(control); 21848712Ssklower msghdr.msg_namelen = (dgramp ? (sizeof name) : 0); 21944323Ssklower iov->iov_len = sizeof(readbuf); 220*55605Ssklower if (select_mode) 221*55605Ssklower sel_recvwait(ns); 22244323Ssklower n = recvmsg(ns, &msghdr, 0); 22344323Ssklower flags = msghdr.msg_flags; 22444323Ssklower count++; 22544323Ssklower dbprintf("recvmsg from child %d got %d ctl %d flags %x\n", 22648712Ssklower getpid(), n, (cn = msghdr.msg_controllen), flags); 22744323Ssklower fflush(stdout); 22848712Ssklower if (dgramp && msghdr.msg_namelen && verbose) 22948712Ssklower dumpit("from:\n", name, msghdr.msg_namelen); 23044323Ssklower if (cn && verbose) 23144323Ssklower dumpit("control data:\n", control, cn); 23244323Ssklower if (n < 0) { 23344323Ssklower fprintf(stderr, "errno is %d\n", errno); 23444323Ssklower perror("recvmsg"); 23544323Ssklower /*sleep (10);*/ 23644323Ssklower break; 23744323Ssklower } else { 23844323Ssklower if (verbose) 23944323Ssklower dumpit("data:\n", readbuf, n); 24044323Ssklower } 24150515Ssklower if (echop) 24250515Ssklower savedata(n, flags); 24350515Ssklower if (flags & MSG_EOR) { 24444323Ssklower records++; 24550515Ssklower if (echop) 24650515Ssklower answerback(ns); 24744323Ssklower } 24844323Ssklower errno = 0; 24944323Ssklower } 25050890Ssklower myexit(0); 25144323Ssklower } 25244323Ssklower } 25344323Ssklower } 25450515Ssklower struct savebuf { 25550515Ssklower struct savebuf *s_next; 25650515Ssklower struct savebuf *s_prev; 25750515Ssklower int s_n; 25850515Ssklower int s_flags; 25950515Ssklower } savebuf = {&savebuf, &savebuf}; 26050515Ssklower 26150515Ssklower void 26250515Ssklower savedata(n, flags) 26350515Ssklower int n, flags; 26444323Ssklower { 26550515Ssklower register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s); 26650515Ssklower if (s == 0) 26750515Ssklower return; 26850515Ssklower insque(s, savebuf.s_prev); 26950515Ssklower s->s_n = n; 27050515Ssklower s->s_flags = flags; 27150515Ssklower bcopy(readbuf, (char *)(s + 1), n); 27244323Ssklower } 27344323Ssklower 27450515Ssklower answerback(ns) 27550515Ssklower { 27650515Ssklower int n; 27750515Ssklower register struct savebuf *s = savebuf.s_next, *t; 27850515Ssklower static struct iovec iov[1]; 27950515Ssklower static struct msghdr msghdr = { 0, 0, iov, 1, 0, 0, 0}; 28050515Ssklower while (s != &savebuf) { 28150515Ssklower iov->iov_len = s->s_n; 28250515Ssklower iov->iov_base = (char *)(s + 1); 28350515Ssklower n = sendmsg(ns, &msghdr, s->s_flags); 28450515Ssklower dbprintf("echoed %d\n", n); 28550515Ssklower t = s; s = s->s_next; remque(t); free((char *)t); 28650515Ssklower } 28750515Ssklower } 28850515Ssklower 28944323Ssklower dumpit(what, where, n) 29044323Ssklower char *what; unsigned short *where; int n; 29144323Ssklower { 29244323Ssklower unsigned short *s = where; 29344323Ssklower unsigned short *z = where + (n+1)/2; 29444323Ssklower int count = 0; 29550890Ssklower if (dumpnodata) 29650890Ssklower return; 29744323Ssklower printf(what); 29844323Ssklower while(s < z) { 29944323Ssklower count++; 30044323Ssklower printf("%x ",*s++); 30144323Ssklower if ((count & 15) == 0) 30244323Ssklower putchar('\n'); 30344323Ssklower } 30444323Ssklower if (count & 15) 30544323Ssklower putchar('\n'); 30644323Ssklower fflush(stdout); 30744323Ssklower } 30844323Ssklower myexit(n) 30944323Ssklower { 31044323Ssklower fflush(stderr); 31144323Ssklower printf("got %d records\n", records); 31244323Ssklower fflush(stdout); 31344323Ssklower exit(n); 31444323Ssklower } 315*55605Ssklower 316*55605Ssklower sel_recvwait(fd) 317*55605Ssklower int fd; 318*55605Ssklower { 319*55605Ssklower int x; 320*55605Ssklower do { 321*55605Ssklower FD_ZERO(&readfds); 322*55605Ssklower FD_ZERO(&exceptfds); 323*55605Ssklower FD_SET(fd, &readfds); 324*55605Ssklower FD_SET(fd, &exceptfds); 325*55605Ssklower x = select(fd+1, &readfds, (fd_set *)0, &exceptfds, (void *)0); 326*55605Ssklower dbprintf("select returns %d\n", x); 327*55605Ssklower } while (x <= 0 || 328*55605Ssklower (FD_ISSET(fd,&readfds) == 0 && FD_ISSET(fd,&exceptfds) == 0)); 329*55605Ssklower } 330*55605Ssklower 331*55605Ssklower #include <sys/syscall.h> 332*55605Ssklower /* Here for gdb trapping */ 333*55605Ssklower setsockopt(s, level, optname, optval, optlen) 334*55605Ssklower int s, level, optname, optlen; 335*55605Ssklower const void *optval; 336*55605Ssklower { 337*55605Ssklower 338*55605Ssklower dbprintf("setsocket called s %d, level 0x%x, optname %d, optlen %d\n", 339*55605Ssklower s, level, optname, optlen); 340*55605Ssklower dumpit("", optval, optlen); 341*55605Ssklower return syscall(SYS_setsockopt, s, level, optname, optval, optlen); 342*55605Ssklower } 343