1*49352Sbostic /*- 2*49352Sbostic * Copyright (c) 1988, 1990 The Regents of the University of California. 344323Ssklower * All rights reserved. 444323Ssklower * 544323Ssklower * %sccs.include.redist.c% 644323Ssklower */ 7*49352Sbostic 844323Ssklower #ifndef lint 9*49352Sbostic char copyright[] = 10*49352Sbostic "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\ 11*49352Sbostic All rights reserved.\n"; 1244323Ssklower #endif /* not lint */ 1344323Ssklower 14*49352Sbostic #ifndef lint 15*49352Sbostic static char sccsid[] = "@(#)tisrc.c 7.5 (Berkeley) 05/07/91"; 16*49352Sbostic #endif /* not lint */ 17*49352Sbostic 1844323Ssklower /* 1948713Ssklower * This is a test program to be a source for ISO transport. 2044323Ssklower */ 2144323Ssklower #include <sys/types.h> 2244323Ssklower #include <sys/socket.h> 2344323Ssklower #include <sys/uio.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_user.h> 3044323Ssklower 3144323Ssklower #include <stdio.h> 3244323Ssklower #include <errno.h> 3344323Ssklower #include <ctype.h> 3444323Ssklower #include <netdb.h> 3544323Ssklower 3644323Ssklower 3744323Ssklower #define dbprintf if(verbose)printf 3844323Ssklower #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\ 3944323Ssklower if (x < 0) {perror("a"); exit(1);}} 4044323Ssklower 4144323Ssklower struct iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/}; 4249065Ssklower struct iso_addr *iso_addr(); 4344323Ssklower struct sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s; 4448713Ssklower struct sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s; 4548843Ssklower struct tp_conn_param tp_params; 4644323Ssklower fd_set readfds, writefds, exceptfds; 4744323Ssklower long size, count = 10; 4844323Ssklower int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0; 4948843Ssklower int verify = 0, dgramp = 0, debug = 0, tp0mode = 1; 5044323Ssklower short portnumber = 3000; 5144323Ssklower char your_it[] = "You're it!"; 5248713Ssklower char *Servername, *conndata, data_msg[2048]; 5348713Ssklower char Serverbuf[128]; 5448713Ssklower char name[128]; 5544323Ssklower struct iovec iov[1] = {data_msg}; 5644323Ssklower union { 5744323Ssklower struct { 5844323Ssklower struct cmsghdr cmhdr; 5948713Ssklower char cmdata[128 - sizeof(struct cmsghdr)]; 6044323Ssklower } cm; 6144323Ssklower char data[128]; 6244323Ssklower } cm; 6344323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; 6444323Ssklower 6544323Ssklower main(argc, argv) 6644323Ssklower int argc; 6744323Ssklower char *argv[]; 6844323Ssklower { 6944323Ssklower register char **av = argv; 7044323Ssklower register char *cp; 7144323Ssklower u_long len; 7244323Ssklower int handy; 7344323Ssklower 7444323Ssklower while(--argc > 0) { 7544323Ssklower av++; 7644323Ssklower if(strcmp(*av,"Servername")==0) { 7744323Ssklower av++; 7848713Ssklower Servername = *av; 7944323Ssklower argc--; 8044323Ssklower } else if(strcmp(*av,"conndata")==0) { 8144323Ssklower av++; 8244323Ssklower conndata = *av; 8344323Ssklower argc--; 8444323Ssklower } else if(strcmp(*av,"host")==0) { 8544323Ssklower av++; 8648713Ssklower to_s.siso_addr = *iso_addr(*av); 8744323Ssklower argc--; 8844323Ssklower } else if(strcmp(*av,"port")==0) { 8944323Ssklower av++; 9044323Ssklower sscanf(*av,"%hd",&portnumber); 9144323Ssklower argc--; 9244323Ssklower } else if(strcmp(*av,"count")==0) { 9344323Ssklower av++; 9444323Ssklower sscanf(*av,"%ld",&count); 9544323Ssklower argc--; 9644323Ssklower } else if(strcmp(*av,"size")==0) { 9744323Ssklower av++; 9844323Ssklower sscanf(*av,"%ld",&size); 9944323Ssklower iov->iov_len = size; 10044323Ssklower } else if(strcmp(*av,"stream")==0) { 10144323Ssklower type = SOCK_STREAM; 10244323Ssklower } else if (strcmp(*av,"eon") == 0) { 10344323Ssklower unsigned long l, inet_addr(); 10444323Ssklower 10544323Ssklower l = inet_addr(*++av); argc--; 10644323Ssklower to_s.siso_addr = eon; 10744323Ssklower bcopy((char *)&l, &to_s.siso_data[15], 4); 10844323Ssklower } 10944323Ssklower } 11048713Ssklower maketoaddr(); 11148713Ssklower tisrc(); 11248713Ssklower } 11348713Ssklower 11448713Ssklower maketoaddr() 11548713Ssklower { 11648713Ssklower if (Servername) { 11748713Ssklower int tlen = strlen(Servername); 11848713Ssklower int len = tlen + TSEL(to) - (caddr_t) to; 11948713Ssklower if (len < sizeof(*to)) len = sizeof(*to); 12048713Ssklower if (len > to->siso_len) { 12149065Ssklower old = to; 12244323Ssklower to = (struct sockaddr_iso *)malloc(len); 12349065Ssklower *to = *old; /* We dont care if all old tsel is copied*/ 12449065Ssklower if (old != &to_s) free(old); 12544323Ssklower } 12649065Ssklower bcopy(Servername, TSEL(to), tlen); 12749065Ssklower to->siso_tlen = tlen; 12844323Ssklower } else { 12949065Ssklower to->siso_tlen = sizeof(portnumber); 13044323Ssklower portnumber = htons(portnumber); 13149065Ssklower bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber)); 13244323Ssklower } 13344323Ssklower } 13444323Ssklower 13544323Ssklower tisrc() { 13648843Ssklower int x, s, pid, on = 1, flags = 8, n, proto = tp0mode ? ISOPROTO_TP0: 0; 13744323Ssklower 13848713Ssklower if (dgramp) type = SOCK_DGRAM; 13948843Ssklower try(socket, (AF_ISO, type, proto),""); 14044323Ssklower s = x; 14144323Ssklower 14248713Ssklower if (debug) 14348713Ssklower try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), ""); 14448713Ssklower if (dgramp == 0) { 14548713Ssklower if (conndata) 14648713Ssklower doconndata(s); 14748713Ssklower try(connect, (s, (struct sockaddr *) to, to->siso_len), ""); 14848713Ssklower } 14944323Ssklower if (selectp) { 15044323Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds); 15144323Ssklower select(1, &writefds, 0, 0, 0); 15244323Ssklower } 15344323Ssklower while (count-- > 0) { 15444323Ssklower if (size <= 0 && get_record(&flags) == EOF) 15544323Ssklower exit(0); 15644323Ssklower n = put_record(s, flags); 15744323Ssklower if (n < iov->iov_len) { 15844323Ssklower if (n==-1 && errno == 55) { 15944323Ssklower nobuffs++; 16044323Ssklower count++; 16144323Ssklower continue; 16244323Ssklower } 16344323Ssklower fprintf(stderr, "wrote %d < %d, count %d,", 16444323Ssklower n, iov->iov_len, count); 16544323Ssklower perror("due to"); 16644323Ssklower } 16744323Ssklower } 16844323Ssklower if (playtag) { 16944323Ssklower printf("Tag time!\n"); 17044323Ssklower iov->iov_base = your_it; 17144323Ssklower iov->iov_len = sizeof your_it; 17244323Ssklower sendmsg(s, &msg, MSG_EOR); 17344323Ssklower sendmsg(s, &msg, MSG_EOR); 17444323Ssklower iov->iov_base = data_msg; 17544323Ssklower iov->iov_len = sizeof data_msg; 17644323Ssklower try(recvmsg, (s, &msg, flags), " playtag "); 17744323Ssklower } 17844323Ssklower if(nobuffs) { 17944323Ssklower printf("looped %d times waiting for bufs\n", nobuffs); 18044323Ssklower } 18144323Ssklower } 18244323Ssklower int localsize; 18344323Ssklower char dupbuf[4096]; 18444323Ssklower 18544323Ssklower put_record(s, flags) 18644323Ssklower int s, flags; 18744323Ssklower { 18844323Ssklower int fd, buflen; 18944323Ssklower char *buf; 19044323Ssklower int x, saved_x; 19144323Ssklower 19244323Ssklower msg.msg_flags = flags; 19344323Ssklower if (verbose) { 19444323Ssklower if (msg.msg_controllen) { 19544323Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 19648713Ssklower dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen); 19744323Ssklower } 19844323Ssklower if (iov->iov_len) { 19944323Ssklower printf("sending: %s %s", 20044323Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""), 20144323Ssklower (flags & MSG_EOR ? "(Record Mark)" : "")); 20248713Ssklower dumpit("data: ", data_msg, localsize); 20344323Ssklower } 20444323Ssklower } 20544323Ssklower if (verify) { 20644323Ssklower buflen = iov->iov_len; 20744323Ssklower bcopy(iov->iov_base, dupbuf, buflen); 20844323Ssklower } 20948713Ssklower if (dgramp) { 21048713Ssklower msg.msg_name = (caddr_t)to; 21148713Ssklower msg.msg_namelen = to->siso_len; 21248713Ssklower } 21344323Ssklower try(sendmsg, (s, &msg, flags), " put_record "); 21444323Ssklower saved_x = x; 21544323Ssklower while (verify && buflen > 0) { 21644323Ssklower iov->iov_len = buflen; 21744323Ssklower iov->iov_base = dupbuf; 21844323Ssklower try(recvmsg, (s, &msg, flags), " put_record "); 21948713Ssklower if (dgramp) { 22048713Ssklower if (msg.msg_namelen) 22148713Ssklower dumpit("from: ", to, msg.msg_namelen); 22248713Ssklower msg.msg_namelen = old->siso_len; 22348713Ssklower } 22444323Ssklower printf("verify got %d\n", x); 22544323Ssklower buflen -= x; 22644323Ssklower } 22748713Ssklower bcopy(old, to, old->siso_len); 22844323Ssklower msg.msg_control = 0; 22944323Ssklower return (saved_x); 23044323Ssklower } 23148713Ssklower dumpit(what, where, n) 23248713Ssklower char *what; unsigned short *where; int n; 23348713Ssklower { 23448713Ssklower unsigned short *s = where; 23548713Ssklower unsigned short *z = where + (n+1)/2; 23648713Ssklower int count = 0; 23748713Ssklower if (verbose == 0) 23848713Ssklower return; 23948713Ssklower printf(what); 24048713Ssklower while(s < z) { 24148713Ssklower count++; 24248713Ssklower printf("%x ",*s++); 24348713Ssklower if ((count & 15) == 0) 24448713Ssklower putchar('\n'); 24548713Ssklower } 24648713Ssklower if (count & 15) 24748713Ssklower putchar('\n'); 24848713Ssklower fflush(stdout); 24948713Ssklower } 25044323Ssklower int *datasize = &iov->iov_len; 25144323Ssklower char *cp, *cplim; 25244323Ssklower 25344323Ssklower get_control_data(type) 25444323Ssklower { 25544323Ssklower 25644323Ssklower datasize = (int *)&msg.msg_controllen; 25744323Ssklower cp = cm.cm.cmdata; 25844323Ssklower cplim = cp + sizeof(cm.cm.cmdata); 25944323Ssklower cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 26044323Ssklower cm.cm.cmhdr.cmsg_type = type; 26144323Ssklower msg.msg_control = cm.data; 26244323Ssklower } 26344323Ssklower 26444323Ssklower doconndata(s) 26544323Ssklower { 26644323Ssklower get_control_data(TPOPT_CONN_DATA); 26744323Ssklower *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr); 26844323Ssklower cm.cm.cmhdr.cmsg_len = *datasize; 26944323Ssklower bcopy(conndata, cp, *datasize); 27044323Ssklower put_record(s, 0); 27144323Ssklower } 27244323Ssklower 27348713Ssklower get_altbuf(addrbuf) 27448713Ssklower char *addrbuf; 27548713Ssklower { 27648713Ssklower if (dgramp == 0) { 27748713Ssklower printf("illegal option for stream\n"); 27848713Ssklower return 1; 27948713Ssklower } 28048713Ssklower return (scanf("%s", addrbuf) == EOF ? 1 : 0); 28148713Ssklower } 28244323Ssklower 28344323Ssklower get_record(flags) 28444323Ssklower int *flags; 28544323Ssklower { 28648713Ssklower int factor = 1, x = 0, newaddr = 0; 28748713Ssklower static repeatcount, repeatsize; 28844323Ssklower char workbuf[10240]; 28948713Ssklower char addrbuf[128]; 29044323Ssklower 29148713Ssklower if (repeatcount > 0) { 29248713Ssklower repeatcount--; 29348713Ssklower return; 29448713Ssklower } 29548713Ssklower 29644323Ssklower *flags = 0; 29744323Ssklower *datasize = 0; 29844323Ssklower datasize = &iov->iov_len; 29944323Ssklower cp = data_msg; 30044323Ssklower cplim = cp + sizeof(data_msg); 30144323Ssklower 30244323Ssklower for(;;) { 30344323Ssklower x = scanf("%s", workbuf); 30444323Ssklower if (x == EOF) 30544323Ssklower break; 30648713Ssklower if (strcmp(workbuf, "host") == 0) { 30748713Ssklower if (get_altbuf(addrbuf)) 30848713Ssklower break; 30948713Ssklower to->siso_addr = *iso_addr(addrbuf); 31048713Ssklower newaddr = 1; 31148713Ssklower } else if (strcmp(workbuf, "Servername") == 0) { 31248713Ssklower if (get_altbuf(Serverbuf)) 31348713Ssklower break; 31448713Ssklower Servername = Serverbuf; 31548713Ssklower newaddr = 1; 31648713Ssklower } else if (strcmp(workbuf, "port") == 0) { 31748713Ssklower x = scanf("%hd", &portnumber); 31848713Ssklower if (x == EOF) 31948713Ssklower break; 32048713Ssklower Servername = 0; 32148713Ssklower newaddr = 1; 32248713Ssklower } else if (strcmp(workbuf, "repeat") == 0) { 32348713Ssklower x = scanf("%d", &repeatcount); 32448713Ssklower if (repeatcount <= 0) repeatcount = 1; 32548713Ssklower repeatcount--; 32648713Ssklower if (x == EOF) 32748713Ssklower break; 32848713Ssklower } else if (strcmp(workbuf, "disc") == 0) 32944323Ssklower x = get_control_data(TPOPT_DISC_DATA); 33044323Ssklower else if (strcmp(workbuf, "cfrm") == 0) 33144323Ssklower x = get_control_data(TPOPT_CFRM_DATA); 33244323Ssklower else if (strcmp(workbuf, "oob") == 0) 33344323Ssklower *flags |= MSG_OOB; 33444323Ssklower else if (strcmp(workbuf, "eom") == 0) 33544323Ssklower *flags |= MSG_EOR; 33644323Ssklower else if (strcmp(workbuf, "factor") == 0) { 33744323Ssklower x = scanf("%d", &factor); 33844323Ssklower if (factor <= 0) factor = 1; 33944323Ssklower if (x == EOF) 34044323Ssklower break; 34144323Ssklower } else { 34244323Ssklower int len = strlen(workbuf); 34344323Ssklower localsize = 0; 34444323Ssklower while ((factor-- > 0) && 34544323Ssklower ((cp + len) < cplim)) { 34644323Ssklower strcpy(cp, workbuf); 34744323Ssklower cp += len; 34844323Ssklower localsize += len; 34944323Ssklower } 35044323Ssklower *datasize = localsize; 35144323Ssklower if (datasize != &iov->iov_len) { 35244323Ssklower *datasize += sizeof(cm.cm.cmhdr); 35348713Ssklower repeatsize = cm.cm.cmhdr.cmsg_len = *datasize; 35444323Ssklower } 35544323Ssklower break; 35644323Ssklower } 35744323Ssklower } 35844323Ssklower errno = 0; 35948713Ssklower if (newaddr) 36048713Ssklower maketoaddr(); 36144323Ssklower return (x); 36244323Ssklower } 363