144323Ssklower /* 248713Ssklower * Copyright (c) 1989, 1990 Regents of the University of California. 344323Ssklower * All rights reserved. 444323Ssklower * 544323Ssklower * %sccs.include.redist.c% 644323Ssklower */ 744323Ssklower #ifndef lint 8*48843Ssklower static char sccsid[] = "@(#)tisrc.c 7.3 (Berkeley) 04/29/91"; 944323Ssklower #endif /* not lint */ 1044323Ssklower 1144323Ssklower /* 1248713Ssklower * This is a test program to be a source for ISO transport. 1344323Ssklower */ 1444323Ssklower #include <sys/types.h> 1544323Ssklower #include <sys/socket.h> 1644323Ssklower #include <sys/uio.h> 1744323Ssklower #include <sys/ioctl.h> 1844323Ssklower #include <net/route.h> 1944323Ssklower #include <net/if.h> 2044323Ssklower #define TCPT_NTIMERS 4 2144323Ssklower #include <netiso/iso.h> 2244323Ssklower #include <netiso/tp_user.h> 2344323Ssklower 2444323Ssklower #include <stdio.h> 2544323Ssklower #include <errno.h> 2644323Ssklower #include <ctype.h> 2744323Ssklower #include <netdb.h> 2844323Ssklower 2944323Ssklower 3044323Ssklower #define dbprintf if(verbose)printf 3144323Ssklower #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\ 3244323Ssklower if (x < 0) {perror("a"); exit(1);}} 3344323Ssklower 3444323Ssklower struct iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/}; 3544323Ssklower struct sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s; 3648713Ssklower struct sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s; 37*48843Ssklower struct tp_conn_param tp_params; 3844323Ssklower fd_set readfds, writefds, exceptfds; 3944323Ssklower long size, count = 10; 4044323Ssklower int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0; 41*48843Ssklower int verify = 0, dgramp = 0, debug = 0, tp0mode = 1; 4244323Ssklower short portnumber = 3000; 4344323Ssklower char your_it[] = "You're it!"; 4448713Ssklower char *Servername, *conndata, data_msg[2048]; 4548713Ssklower char Serverbuf[128]; 4648713Ssklower char name[128]; 4744323Ssklower struct iovec iov[1] = {data_msg}; 4844323Ssklower union { 4944323Ssklower struct { 5044323Ssklower struct cmsghdr cmhdr; 5148713Ssklower char cmdata[128 - sizeof(struct cmsghdr)]; 5244323Ssklower } cm; 5344323Ssklower char data[128]; 5444323Ssklower } cm; 5544323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; 5644323Ssklower 5744323Ssklower main(argc, argv) 5844323Ssklower int argc; 5944323Ssklower char *argv[]; 6044323Ssklower { 6144323Ssklower register char **av = argv; 6244323Ssklower register char *cp; 6344323Ssklower u_long len; 6444323Ssklower int handy; 6544323Ssklower 6644323Ssklower while(--argc > 0) { 6744323Ssklower av++; 6844323Ssklower if(strcmp(*av,"Servername")==0) { 6944323Ssklower av++; 7048713Ssklower Servername = *av; 7144323Ssklower argc--; 7244323Ssklower } else if(strcmp(*av,"conndata")==0) { 7344323Ssklower av++; 7444323Ssklower conndata = *av; 7544323Ssklower argc--; 7644323Ssklower } else if(strcmp(*av,"host")==0) { 7744323Ssklower av++; 7848713Ssklower to_s.siso_addr = *iso_addr(*av); 7944323Ssklower argc--; 8044323Ssklower } else if(strcmp(*av,"port")==0) { 8144323Ssklower av++; 8244323Ssklower sscanf(*av,"%hd",&portnumber); 8344323Ssklower argc--; 8444323Ssklower } else if(strcmp(*av,"count")==0) { 8544323Ssklower av++; 8644323Ssklower sscanf(*av,"%ld",&count); 8744323Ssklower argc--; 8844323Ssklower } else if(strcmp(*av,"size")==0) { 8944323Ssklower av++; 9044323Ssklower sscanf(*av,"%ld",&size); 9144323Ssklower iov->iov_len = size; 9244323Ssklower } else if(strcmp(*av,"stream")==0) { 9344323Ssklower type = SOCK_STREAM; 9444323Ssklower } else if (strcmp(*av,"eon") == 0) { 9544323Ssklower unsigned long l, inet_addr(); 9644323Ssklower 9744323Ssklower l = inet_addr(*++av); argc--; 9844323Ssklower to_s.siso_addr = eon; 9944323Ssklower bcopy((char *)&l, &to_s.siso_data[15], 4); 10044323Ssklower } 10144323Ssklower } 10248713Ssklower maketoaddr(); 10348713Ssklower tisrc(); 10448713Ssklower } 10548713Ssklower 10648713Ssklower maketoaddr() 10748713Ssklower { 10848713Ssklower if (Servername) { 10948713Ssklower int tlen = strlen(Servername); 11048713Ssklower int len = tlen + TSEL(to) - (caddr_t) to; 11148713Ssklower if (len < sizeof(*to)) len = sizeof(*to); 11248713Ssklower if (len > to->siso_len) { 11348713Ssklower if (old != &old_s) free(old); 11448713Ssklower old = (struct sockaddr_iso *)malloc(len); 11548713Ssklower *old = *to; /* We dont care if all old tsel is copied*/ 11648713Ssklower old->siso_len = len; 11748713Ssklower if (to != &to_s) free(to); 11844323Ssklower to = (struct sockaddr_iso *)malloc(len); 11944323Ssklower } 12048713Ssklower bcopy(Servername, TSEL(old), tlen); 12144323Ssklower } else { 12248713Ssklower old->siso_tlen = sizeof(portnumber); 12344323Ssklower portnumber = htons(portnumber); 12448713Ssklower bcopy((char *)&portnumber, TSEL(old), sizeof(portnumber)); 12544323Ssklower } 12648713Ssklower bcopy(old, to, old->siso_len); 12744323Ssklower } 12844323Ssklower 12944323Ssklower tisrc() { 130*48843Ssklower int x, s, pid, on = 1, flags = 8, n, proto = tp0mode ? ISOPROTO_TP0: 0; 13144323Ssklower 13248713Ssklower if (dgramp) type = SOCK_DGRAM; 133*48843Ssklower try(socket, (AF_ISO, type, proto),""); 13444323Ssklower s = x; 13544323Ssklower 13648713Ssklower if (debug) 13748713Ssklower try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), ""); 13848713Ssklower if (dgramp == 0) { 13948713Ssklower if (conndata) 14048713Ssklower doconndata(s); 14148713Ssklower try(connect, (s, (struct sockaddr *) to, to->siso_len), ""); 14248713Ssklower } 14344323Ssklower if (selectp) { 14444323Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds); 14544323Ssklower select(1, &writefds, 0, 0, 0); 14644323Ssklower } 14744323Ssklower while (count-- > 0) { 14844323Ssklower if (size <= 0 && get_record(&flags) == EOF) 14944323Ssklower exit(0); 15044323Ssklower n = put_record(s, flags); 15144323Ssklower if (n < iov->iov_len) { 15244323Ssklower if (n==-1 && errno == 55) { 15344323Ssklower nobuffs++; 15444323Ssklower count++; 15544323Ssklower continue; 15644323Ssklower } 15744323Ssklower fprintf(stderr, "wrote %d < %d, count %d,", 15844323Ssklower n, iov->iov_len, count); 15944323Ssklower perror("due to"); 16044323Ssklower } 16144323Ssklower } 16244323Ssklower if (playtag) { 16344323Ssklower printf("Tag time!\n"); 16444323Ssklower iov->iov_base = your_it; 16544323Ssklower iov->iov_len = sizeof your_it; 16644323Ssklower sendmsg(s, &msg, MSG_EOR); 16744323Ssklower sendmsg(s, &msg, MSG_EOR); 16844323Ssklower iov->iov_base = data_msg; 16944323Ssklower iov->iov_len = sizeof data_msg; 17044323Ssklower try(recvmsg, (s, &msg, flags), " playtag "); 17144323Ssklower } 17244323Ssklower if(nobuffs) { 17344323Ssklower printf("looped %d times waiting for bufs\n", nobuffs); 17444323Ssklower } 17544323Ssklower } 17644323Ssklower int localsize; 17744323Ssklower char dupbuf[4096]; 17844323Ssklower 17944323Ssklower put_record(s, flags) 18044323Ssklower int s, flags; 18144323Ssklower { 18244323Ssklower int fd, buflen; 18344323Ssklower char *buf; 18444323Ssklower int x, saved_x; 18544323Ssklower 18644323Ssklower msg.msg_flags = flags; 18744323Ssklower if (verbose) { 18844323Ssklower if (msg.msg_controllen) { 18944323Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 19048713Ssklower dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen); 19144323Ssklower } 19244323Ssklower if (iov->iov_len) { 19344323Ssklower printf("sending: %s %s", 19444323Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""), 19544323Ssklower (flags & MSG_EOR ? "(Record Mark)" : "")); 19648713Ssklower dumpit("data: ", data_msg, localsize); 19744323Ssklower } 19844323Ssklower } 19944323Ssklower if (verify) { 20044323Ssklower buflen = iov->iov_len; 20144323Ssklower bcopy(iov->iov_base, dupbuf, buflen); 20244323Ssklower } 20348713Ssklower if (dgramp) { 20448713Ssklower msg.msg_name = (caddr_t)to; 20548713Ssklower msg.msg_namelen = to->siso_len; 20648713Ssklower } 20744323Ssklower try(sendmsg, (s, &msg, flags), " put_record "); 20844323Ssklower saved_x = x; 20944323Ssklower while (verify && buflen > 0) { 21044323Ssklower iov->iov_len = buflen; 21144323Ssklower iov->iov_base = dupbuf; 21244323Ssklower try(recvmsg, (s, &msg, flags), " put_record "); 21348713Ssklower if (dgramp) { 21448713Ssklower if (msg.msg_namelen) 21548713Ssklower dumpit("from: ", to, msg.msg_namelen); 21648713Ssklower msg.msg_namelen = old->siso_len; 21748713Ssklower } 21844323Ssklower printf("verify got %d\n", x); 21944323Ssklower buflen -= x; 22044323Ssklower } 22148713Ssklower bcopy(old, to, old->siso_len); 22244323Ssklower msg.msg_control = 0; 22344323Ssklower return (saved_x); 22444323Ssklower } 22548713Ssklower dumpit(what, where, n) 22648713Ssklower char *what; unsigned short *where; int n; 22748713Ssklower { 22848713Ssklower unsigned short *s = where; 22948713Ssklower unsigned short *z = where + (n+1)/2; 23048713Ssklower int count = 0; 23148713Ssklower if (verbose == 0) 23248713Ssklower return; 23348713Ssklower printf(what); 23448713Ssklower while(s < z) { 23548713Ssklower count++; 23648713Ssklower printf("%x ",*s++); 23748713Ssklower if ((count & 15) == 0) 23848713Ssklower putchar('\n'); 23948713Ssklower } 24048713Ssklower if (count & 15) 24148713Ssklower putchar('\n'); 24248713Ssklower fflush(stdout); 24348713Ssklower } 24444323Ssklower int *datasize = &iov->iov_len; 24544323Ssklower char *cp, *cplim; 24644323Ssklower 24744323Ssklower get_control_data(type) 24844323Ssklower { 24944323Ssklower 25044323Ssklower datasize = (int *)&msg.msg_controllen; 25144323Ssklower cp = cm.cm.cmdata; 25244323Ssklower cplim = cp + sizeof(cm.cm.cmdata); 25344323Ssklower cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 25444323Ssklower cm.cm.cmhdr.cmsg_type = type; 25544323Ssklower msg.msg_control = cm.data; 25644323Ssklower } 25744323Ssklower 25844323Ssklower doconndata(s) 25944323Ssklower { 26044323Ssklower get_control_data(TPOPT_CONN_DATA); 26144323Ssklower *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr); 26244323Ssklower cm.cm.cmhdr.cmsg_len = *datasize; 26344323Ssklower bcopy(conndata, cp, *datasize); 26444323Ssklower put_record(s, 0); 26544323Ssklower } 26644323Ssklower 26748713Ssklower get_altbuf(addrbuf) 26848713Ssklower char *addrbuf; 26948713Ssklower { 27048713Ssklower if (dgramp == 0) { 27148713Ssklower printf("illegal option for stream\n"); 27248713Ssklower return 1; 27348713Ssklower } 27448713Ssklower return (scanf("%s", addrbuf) == EOF ? 1 : 0); 27548713Ssklower } 27644323Ssklower 27744323Ssklower get_record(flags) 27844323Ssklower int *flags; 27944323Ssklower { 28048713Ssklower int factor = 1, x = 0, newaddr = 0; 28148713Ssklower static repeatcount, repeatsize; 28244323Ssklower char workbuf[10240]; 28348713Ssklower char addrbuf[128]; 28444323Ssklower 28548713Ssklower if (repeatcount > 0) { 28648713Ssklower repeatcount--; 28748713Ssklower return; 28848713Ssklower } 28948713Ssklower 29044323Ssklower *flags = 0; 29144323Ssklower *datasize = 0; 29244323Ssklower datasize = &iov->iov_len; 29344323Ssklower cp = data_msg; 29444323Ssklower cplim = cp + sizeof(data_msg); 29544323Ssklower 29644323Ssklower for(;;) { 29744323Ssklower x = scanf("%s", workbuf); 29844323Ssklower if (x == EOF) 29944323Ssklower break; 30048713Ssklower if (strcmp(workbuf, "host") == 0) { 30148713Ssklower if (get_altbuf(addrbuf)) 30248713Ssklower break; 30348713Ssklower to->siso_addr = *iso_addr(addrbuf); 30448713Ssklower newaddr = 1; 30548713Ssklower } else if (strcmp(workbuf, "Servername") == 0) { 30648713Ssklower if (get_altbuf(Serverbuf)) 30748713Ssklower break; 30848713Ssklower Servername = Serverbuf; 30948713Ssklower newaddr = 1; 31048713Ssklower } else if (strcmp(workbuf, "port") == 0) { 31148713Ssklower x = scanf("%hd", &portnumber); 31248713Ssklower if (x == EOF) 31348713Ssklower break; 31448713Ssklower Servername = 0; 31548713Ssklower newaddr = 1; 31648713Ssklower } else if (strcmp(workbuf, "repeat") == 0) { 31748713Ssklower x = scanf("%d", &repeatcount); 31848713Ssklower if (repeatcount <= 0) repeatcount = 1; 31948713Ssklower repeatcount--; 32048713Ssklower if (x == EOF) 32148713Ssklower break; 32248713Ssklower } else if (strcmp(workbuf, "disc") == 0) 32344323Ssklower x = get_control_data(TPOPT_DISC_DATA); 32444323Ssklower else if (strcmp(workbuf, "cfrm") == 0) 32544323Ssklower x = get_control_data(TPOPT_CFRM_DATA); 32644323Ssklower else if (strcmp(workbuf, "oob") == 0) 32744323Ssklower *flags |= MSG_OOB; 32844323Ssklower else if (strcmp(workbuf, "eom") == 0) 32944323Ssklower *flags |= MSG_EOR; 33044323Ssklower else if (strcmp(workbuf, "factor") == 0) { 33144323Ssklower x = scanf("%d", &factor); 33244323Ssklower if (factor <= 0) factor = 1; 33344323Ssklower if (x == EOF) 33444323Ssklower break; 33544323Ssklower } else { 33644323Ssklower int len = strlen(workbuf); 33744323Ssklower localsize = 0; 33844323Ssklower while ((factor-- > 0) && 33944323Ssklower ((cp + len) < cplim)) { 34044323Ssklower strcpy(cp, workbuf); 34144323Ssklower cp += len; 34244323Ssklower localsize += len; 34344323Ssklower } 34444323Ssklower *datasize = localsize; 34544323Ssklower if (datasize != &iov->iov_len) { 34644323Ssklower *datasize += sizeof(cm.cm.cmhdr); 34748713Ssklower repeatsize = cm.cm.cmhdr.cmsg_len = *datasize; 34844323Ssklower } 34944323Ssklower break; 35044323Ssklower } 35144323Ssklower } 35244323Ssklower errno = 0; 35348713Ssklower if (newaddr) 35448713Ssklower maketoaddr(); 35544323Ssklower return (x); 35644323Ssklower } 357