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*49065Ssklower static char sccsid[] = "@(#)tisrc.c 7.4 (Berkeley) 05/04/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*/}; 35*49065Ssklower struct iso_addr *iso_addr(); 3644323Ssklower struct sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s; 3748713Ssklower struct sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s; 3848843Ssklower struct tp_conn_param tp_params; 3944323Ssklower fd_set readfds, writefds, exceptfds; 4044323Ssklower long size, count = 10; 4144323Ssklower int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0; 4248843Ssklower int verify = 0, dgramp = 0, debug = 0, tp0mode = 1; 4344323Ssklower short portnumber = 3000; 4444323Ssklower char your_it[] = "You're it!"; 4548713Ssklower char *Servername, *conndata, data_msg[2048]; 4648713Ssklower char Serverbuf[128]; 4748713Ssklower char name[128]; 4844323Ssklower struct iovec iov[1] = {data_msg}; 4944323Ssklower union { 5044323Ssklower struct { 5144323Ssklower struct cmsghdr cmhdr; 5248713Ssklower char cmdata[128 - sizeof(struct cmsghdr)]; 5344323Ssklower } cm; 5444323Ssklower char data[128]; 5544323Ssklower } cm; 5644323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; 5744323Ssklower 5844323Ssklower main(argc, argv) 5944323Ssklower int argc; 6044323Ssklower char *argv[]; 6144323Ssklower { 6244323Ssklower register char **av = argv; 6344323Ssklower register char *cp; 6444323Ssklower u_long len; 6544323Ssklower int handy; 6644323Ssklower 6744323Ssklower while(--argc > 0) { 6844323Ssklower av++; 6944323Ssklower if(strcmp(*av,"Servername")==0) { 7044323Ssklower av++; 7148713Ssklower Servername = *av; 7244323Ssklower argc--; 7344323Ssklower } else if(strcmp(*av,"conndata")==0) { 7444323Ssklower av++; 7544323Ssklower conndata = *av; 7644323Ssklower argc--; 7744323Ssklower } else if(strcmp(*av,"host")==0) { 7844323Ssklower av++; 7948713Ssklower to_s.siso_addr = *iso_addr(*av); 8044323Ssklower argc--; 8144323Ssklower } else if(strcmp(*av,"port")==0) { 8244323Ssklower av++; 8344323Ssklower sscanf(*av,"%hd",&portnumber); 8444323Ssklower argc--; 8544323Ssklower } else if(strcmp(*av,"count")==0) { 8644323Ssklower av++; 8744323Ssklower sscanf(*av,"%ld",&count); 8844323Ssklower argc--; 8944323Ssklower } else if(strcmp(*av,"size")==0) { 9044323Ssklower av++; 9144323Ssklower sscanf(*av,"%ld",&size); 9244323Ssklower iov->iov_len = size; 9344323Ssklower } else if(strcmp(*av,"stream")==0) { 9444323Ssklower type = SOCK_STREAM; 9544323Ssklower } else if (strcmp(*av,"eon") == 0) { 9644323Ssklower unsigned long l, inet_addr(); 9744323Ssklower 9844323Ssklower l = inet_addr(*++av); argc--; 9944323Ssklower to_s.siso_addr = eon; 10044323Ssklower bcopy((char *)&l, &to_s.siso_data[15], 4); 10144323Ssklower } 10244323Ssklower } 10348713Ssklower maketoaddr(); 10448713Ssklower tisrc(); 10548713Ssklower } 10648713Ssklower 10748713Ssklower maketoaddr() 10848713Ssklower { 10948713Ssklower if (Servername) { 11048713Ssklower int tlen = strlen(Servername); 11148713Ssklower int len = tlen + TSEL(to) - (caddr_t) to; 11248713Ssklower if (len < sizeof(*to)) len = sizeof(*to); 11348713Ssklower if (len > to->siso_len) { 114*49065Ssklower old = to; 11544323Ssklower to = (struct sockaddr_iso *)malloc(len); 116*49065Ssklower *to = *old; /* We dont care if all old tsel is copied*/ 117*49065Ssklower if (old != &to_s) free(old); 11844323Ssklower } 119*49065Ssklower bcopy(Servername, TSEL(to), tlen); 120*49065Ssklower to->siso_tlen = tlen; 12144323Ssklower } else { 122*49065Ssklower to->siso_tlen = sizeof(portnumber); 12344323Ssklower portnumber = htons(portnumber); 124*49065Ssklower bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber)); 12544323Ssklower } 12644323Ssklower } 12744323Ssklower 12844323Ssklower tisrc() { 12948843Ssklower int x, s, pid, on = 1, flags = 8, n, proto = tp0mode ? ISOPROTO_TP0: 0; 13044323Ssklower 13148713Ssklower if (dgramp) type = SOCK_DGRAM; 13248843Ssklower try(socket, (AF_ISO, type, proto),""); 13344323Ssklower s = x; 13444323Ssklower 13548713Ssklower if (debug) 13648713Ssklower try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), ""); 13748713Ssklower if (dgramp == 0) { 13848713Ssklower if (conndata) 13948713Ssklower doconndata(s); 14048713Ssklower try(connect, (s, (struct sockaddr *) to, to->siso_len), ""); 14148713Ssklower } 14244323Ssklower if (selectp) { 14344323Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds); 14444323Ssklower select(1, &writefds, 0, 0, 0); 14544323Ssklower } 14644323Ssklower while (count-- > 0) { 14744323Ssklower if (size <= 0 && get_record(&flags) == EOF) 14844323Ssklower exit(0); 14944323Ssklower n = put_record(s, flags); 15044323Ssklower if (n < iov->iov_len) { 15144323Ssklower if (n==-1 && errno == 55) { 15244323Ssklower nobuffs++; 15344323Ssklower count++; 15444323Ssklower continue; 15544323Ssklower } 15644323Ssklower fprintf(stderr, "wrote %d < %d, count %d,", 15744323Ssklower n, iov->iov_len, count); 15844323Ssklower perror("due to"); 15944323Ssklower } 16044323Ssklower } 16144323Ssklower if (playtag) { 16244323Ssklower printf("Tag time!\n"); 16344323Ssklower iov->iov_base = your_it; 16444323Ssklower iov->iov_len = sizeof your_it; 16544323Ssklower sendmsg(s, &msg, MSG_EOR); 16644323Ssklower sendmsg(s, &msg, MSG_EOR); 16744323Ssklower iov->iov_base = data_msg; 16844323Ssklower iov->iov_len = sizeof data_msg; 16944323Ssklower try(recvmsg, (s, &msg, flags), " playtag "); 17044323Ssklower } 17144323Ssklower if(nobuffs) { 17244323Ssklower printf("looped %d times waiting for bufs\n", nobuffs); 17344323Ssklower } 17444323Ssklower } 17544323Ssklower int localsize; 17644323Ssklower char dupbuf[4096]; 17744323Ssklower 17844323Ssklower put_record(s, flags) 17944323Ssklower int s, flags; 18044323Ssklower { 18144323Ssklower int fd, buflen; 18244323Ssklower char *buf; 18344323Ssklower int x, saved_x; 18444323Ssklower 18544323Ssklower msg.msg_flags = flags; 18644323Ssklower if (verbose) { 18744323Ssklower if (msg.msg_controllen) { 18844323Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 18948713Ssklower dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen); 19044323Ssklower } 19144323Ssklower if (iov->iov_len) { 19244323Ssklower printf("sending: %s %s", 19344323Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""), 19444323Ssklower (flags & MSG_EOR ? "(Record Mark)" : "")); 19548713Ssklower dumpit("data: ", data_msg, localsize); 19644323Ssklower } 19744323Ssklower } 19844323Ssklower if (verify) { 19944323Ssklower buflen = iov->iov_len; 20044323Ssklower bcopy(iov->iov_base, dupbuf, buflen); 20144323Ssklower } 20248713Ssklower if (dgramp) { 20348713Ssklower msg.msg_name = (caddr_t)to; 20448713Ssklower msg.msg_namelen = to->siso_len; 20548713Ssklower } 20644323Ssklower try(sendmsg, (s, &msg, flags), " put_record "); 20744323Ssklower saved_x = x; 20844323Ssklower while (verify && buflen > 0) { 20944323Ssklower iov->iov_len = buflen; 21044323Ssklower iov->iov_base = dupbuf; 21144323Ssklower try(recvmsg, (s, &msg, flags), " put_record "); 21248713Ssklower if (dgramp) { 21348713Ssklower if (msg.msg_namelen) 21448713Ssklower dumpit("from: ", to, msg.msg_namelen); 21548713Ssklower msg.msg_namelen = old->siso_len; 21648713Ssklower } 21744323Ssklower printf("verify got %d\n", x); 21844323Ssklower buflen -= x; 21944323Ssklower } 22048713Ssklower bcopy(old, to, old->siso_len); 22144323Ssklower msg.msg_control = 0; 22244323Ssklower return (saved_x); 22344323Ssklower } 22448713Ssklower dumpit(what, where, n) 22548713Ssklower char *what; unsigned short *where; int n; 22648713Ssklower { 22748713Ssklower unsigned short *s = where; 22848713Ssklower unsigned short *z = where + (n+1)/2; 22948713Ssklower int count = 0; 23048713Ssklower if (verbose == 0) 23148713Ssklower return; 23248713Ssklower printf(what); 23348713Ssklower while(s < z) { 23448713Ssklower count++; 23548713Ssklower printf("%x ",*s++); 23648713Ssklower if ((count & 15) == 0) 23748713Ssklower putchar('\n'); 23848713Ssklower } 23948713Ssklower if (count & 15) 24048713Ssklower putchar('\n'); 24148713Ssklower fflush(stdout); 24248713Ssklower } 24344323Ssklower int *datasize = &iov->iov_len; 24444323Ssklower char *cp, *cplim; 24544323Ssklower 24644323Ssklower get_control_data(type) 24744323Ssklower { 24844323Ssklower 24944323Ssklower datasize = (int *)&msg.msg_controllen; 25044323Ssklower cp = cm.cm.cmdata; 25144323Ssklower cplim = cp + sizeof(cm.cm.cmdata); 25244323Ssklower cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 25344323Ssklower cm.cm.cmhdr.cmsg_type = type; 25444323Ssklower msg.msg_control = cm.data; 25544323Ssklower } 25644323Ssklower 25744323Ssklower doconndata(s) 25844323Ssklower { 25944323Ssklower get_control_data(TPOPT_CONN_DATA); 26044323Ssklower *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr); 26144323Ssklower cm.cm.cmhdr.cmsg_len = *datasize; 26244323Ssklower bcopy(conndata, cp, *datasize); 26344323Ssklower put_record(s, 0); 26444323Ssklower } 26544323Ssklower 26648713Ssklower get_altbuf(addrbuf) 26748713Ssklower char *addrbuf; 26848713Ssklower { 26948713Ssklower if (dgramp == 0) { 27048713Ssklower printf("illegal option for stream\n"); 27148713Ssklower return 1; 27248713Ssklower } 27348713Ssklower return (scanf("%s", addrbuf) == EOF ? 1 : 0); 27448713Ssklower } 27544323Ssklower 27644323Ssklower get_record(flags) 27744323Ssklower int *flags; 27844323Ssklower { 27948713Ssklower int factor = 1, x = 0, newaddr = 0; 28048713Ssklower static repeatcount, repeatsize; 28144323Ssklower char workbuf[10240]; 28248713Ssklower char addrbuf[128]; 28344323Ssklower 28448713Ssklower if (repeatcount > 0) { 28548713Ssklower repeatcount--; 28648713Ssklower return; 28748713Ssklower } 28848713Ssklower 28944323Ssklower *flags = 0; 29044323Ssklower *datasize = 0; 29144323Ssklower datasize = &iov->iov_len; 29244323Ssklower cp = data_msg; 29344323Ssklower cplim = cp + sizeof(data_msg); 29444323Ssklower 29544323Ssklower for(;;) { 29644323Ssklower x = scanf("%s", workbuf); 29744323Ssklower if (x == EOF) 29844323Ssklower break; 29948713Ssklower if (strcmp(workbuf, "host") == 0) { 30048713Ssklower if (get_altbuf(addrbuf)) 30148713Ssklower break; 30248713Ssklower to->siso_addr = *iso_addr(addrbuf); 30348713Ssklower newaddr = 1; 30448713Ssklower } else if (strcmp(workbuf, "Servername") == 0) { 30548713Ssklower if (get_altbuf(Serverbuf)) 30648713Ssklower break; 30748713Ssklower Servername = Serverbuf; 30848713Ssklower newaddr = 1; 30948713Ssklower } else if (strcmp(workbuf, "port") == 0) { 31048713Ssklower x = scanf("%hd", &portnumber); 31148713Ssklower if (x == EOF) 31248713Ssklower break; 31348713Ssklower Servername = 0; 31448713Ssklower newaddr = 1; 31548713Ssklower } else if (strcmp(workbuf, "repeat") == 0) { 31648713Ssklower x = scanf("%d", &repeatcount); 31748713Ssklower if (repeatcount <= 0) repeatcount = 1; 31848713Ssklower repeatcount--; 31948713Ssklower if (x == EOF) 32048713Ssklower break; 32148713Ssklower } else if (strcmp(workbuf, "disc") == 0) 32244323Ssklower x = get_control_data(TPOPT_DISC_DATA); 32344323Ssklower else if (strcmp(workbuf, "cfrm") == 0) 32444323Ssklower x = get_control_data(TPOPT_CFRM_DATA); 32544323Ssklower else if (strcmp(workbuf, "oob") == 0) 32644323Ssklower *flags |= MSG_OOB; 32744323Ssklower else if (strcmp(workbuf, "eom") == 0) 32844323Ssklower *flags |= MSG_EOR; 32944323Ssklower else if (strcmp(workbuf, "factor") == 0) { 33044323Ssklower x = scanf("%d", &factor); 33144323Ssklower if (factor <= 0) factor = 1; 33244323Ssklower if (x == EOF) 33344323Ssklower break; 33444323Ssklower } else { 33544323Ssklower int len = strlen(workbuf); 33644323Ssklower localsize = 0; 33744323Ssklower while ((factor-- > 0) && 33844323Ssklower ((cp + len) < cplim)) { 33944323Ssklower strcpy(cp, workbuf); 34044323Ssklower cp += len; 34144323Ssklower localsize += len; 34244323Ssklower } 34344323Ssklower *datasize = localsize; 34444323Ssklower if (datasize != &iov->iov_len) { 34544323Ssklower *datasize += sizeof(cm.cm.cmhdr); 34648713Ssklower repeatsize = cm.cm.cmhdr.cmsg_len = *datasize; 34744323Ssklower } 34844323Ssklower break; 34944323Ssklower } 35044323Ssklower } 35144323Ssklower errno = 0; 35248713Ssklower if (newaddr) 35348713Ssklower maketoaddr(); 35444323Ssklower return (x); 35544323Ssklower } 356