1*44323Ssklower /* 2*44323Ssklower * Copyright (c) 1988, 1990 Regents of the University of California. 3*44323Ssklower * All rights reserved. 4*44323Ssklower * 5*44323Ssklower * %sccs.include.redist.c% 6*44323Ssklower */ 7*44323Ssklower #ifndef lint 8*44323Ssklower static char sccsid[] = "@(#)tisrc.c 7.1 (Berkeley) 06/27/90"; 9*44323Ssklower #endif /* not lint */ 10*44323Ssklower 11*44323Ssklower /* 12*44323Ssklower * This is a test program to be a source for TP4 connections. 13*44323Ssklower */ 14*44323Ssklower #include <sys/types.h> 15*44323Ssklower #include <sys/socket.h> 16*44323Ssklower #include <sys/uio.h> 17*44323Ssklower #include <sys/ioctl.h> 18*44323Ssklower #include <net/route.h> 19*44323Ssklower #include <net/if.h> 20*44323Ssklower #define TCPT_NTIMERS 4 21*44323Ssklower #include <netiso/iso.h> 22*44323Ssklower #include <netiso/tp_user.h> 23*44323Ssklower 24*44323Ssklower #include <stdio.h> 25*44323Ssklower #include <errno.h> 26*44323Ssklower #include <ctype.h> 27*44323Ssklower #include <netdb.h> 28*44323Ssklower 29*44323Ssklower 30*44323Ssklower #define dbprintf if(verbose)printf 31*44323Ssklower #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\ 32*44323Ssklower if (x < 0) {perror("a"); exit(1);}} 33*44323Ssklower 34*44323Ssklower struct iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/}; 35*44323Ssklower struct sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s; 36*44323Ssklower fd_set readfds, writefds, exceptfds; 37*44323Ssklower long size, count = 10; 38*44323Ssklower int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0; 39*44323Ssklower int verify = 0; 40*44323Ssklower short portnumber = 3000; 41*44323Ssklower char your_it[] = "You're it!"; 42*44323Ssklower char *port, *conndata, data_msg[2048]; 43*44323Ssklower struct iovec iov[1] = {data_msg}; 44*44323Ssklower union { 45*44323Ssklower struct { 46*44323Ssklower struct cmsghdr cmhdr; 47*44323Ssklower char cmdata[128 - sizeof (struct cmsghdr)]; 48*44323Ssklower } cm; 49*44323Ssklower char data[128]; 50*44323Ssklower } cm; 51*44323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; 52*44323Ssklower 53*44323Ssklower main(argc, argv) 54*44323Ssklower int argc; 55*44323Ssklower char *argv[]; 56*44323Ssklower { 57*44323Ssklower register char **av = argv; 58*44323Ssklower register char *cp; 59*44323Ssklower struct iso_addr iso_addr(); 60*44323Ssklower u_long len; 61*44323Ssklower int handy; 62*44323Ssklower 63*44323Ssklower while(--argc > 0) { 64*44323Ssklower av++; 65*44323Ssklower if(strcmp(*av,"Servername")==0) { 66*44323Ssklower av++; 67*44323Ssklower port = *av; 68*44323Ssklower argc--; 69*44323Ssklower } else if(strcmp(*av,"conndata")==0) { 70*44323Ssklower av++; 71*44323Ssklower conndata = *av; 72*44323Ssklower argc--; 73*44323Ssklower } else if(strcmp(*av,"host")==0) { 74*44323Ssklower av++; 75*44323Ssklower to_s.siso_addr = iso_addr(*av); 76*44323Ssklower argc--; 77*44323Ssklower } else if(strcmp(*av,"port")==0) { 78*44323Ssklower av++; 79*44323Ssklower sscanf(*av,"%hd",&portnumber); 80*44323Ssklower argc--; 81*44323Ssklower } else if(strcmp(*av,"count")==0) { 82*44323Ssklower av++; 83*44323Ssklower sscanf(*av,"%ld",&count); 84*44323Ssklower argc--; 85*44323Ssklower } else if(strcmp(*av,"size")==0) { 86*44323Ssklower av++; 87*44323Ssklower sscanf(*av,"%ld",&size); 88*44323Ssklower iov->iov_len = size; 89*44323Ssklower } else if(strcmp(*av,"stream")==0) { 90*44323Ssklower type = SOCK_STREAM; 91*44323Ssklower } else if (strcmp(*av,"eon") == 0) { 92*44323Ssklower unsigned long l, inet_addr(); 93*44323Ssklower 94*44323Ssklower l = inet_addr(*++av); argc--; 95*44323Ssklower to_s.siso_addr = eon; 96*44323Ssklower bcopy((char *)&l, &to_s.siso_data[15], 4); 97*44323Ssklower } 98*44323Ssklower } 99*44323Ssklower if (port) { 100*44323Ssklower to_s.siso_tlen = strlen(port); 101*44323Ssklower len = 1 + to_s.siso_nlen + strlen(port) 102*44323Ssklower + sizeof(*to) - sizeof(struct iso_addr); 103*44323Ssklower if (len > sizeof(*to)) { 104*44323Ssklower to = (struct sockaddr_iso *)malloc(len); 105*44323Ssklower bzero(to, len); 106*44323Ssklower *to = to_s; 107*44323Ssklower to->siso_len = len; 108*44323Ssklower } 109*44323Ssklower bcopy(port, TSEL(to), strlen(port)); 110*44323Ssklower } else { 111*44323Ssklower to_s.siso_tlen = sizeof(portnumber); 112*44323Ssklower portnumber = htons(portnumber); 113*44323Ssklower bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber)); 114*44323Ssklower } 115*44323Ssklower 116*44323Ssklower tisrc(); 117*44323Ssklower } 118*44323Ssklower 119*44323Ssklower tisrc() { 120*44323Ssklower int x, s, pid, on = 1, flags = 8, n; 121*44323Ssklower 122*44323Ssklower try(socket, (AF_ISO, type, 0),""); 123*44323Ssklower s = x; 124*44323Ssklower 125*44323Ssklower /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/ 126*44323Ssklower 127*44323Ssklower if (conndata) doconndata(s); 128*44323Ssklower 129*44323Ssklower try(connect, (s, (struct sockaddr *) to, to->siso_len), ""); 130*44323Ssklower 131*44323Ssklower if (selectp) { 132*44323Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds); 133*44323Ssklower select(1, &writefds, 0, 0, 0); 134*44323Ssklower } 135*44323Ssklower while (count-- > 0) { 136*44323Ssklower if (size <= 0 && get_record(&flags) == EOF) 137*44323Ssklower exit(0); 138*44323Ssklower n = put_record(s, flags); 139*44323Ssklower if (n < iov->iov_len) { 140*44323Ssklower if (n==-1 && errno == 55) { 141*44323Ssklower nobuffs++; 142*44323Ssklower count++; 143*44323Ssklower continue; 144*44323Ssklower } 145*44323Ssklower fprintf(stderr, "wrote %d < %d, count %d,", 146*44323Ssklower n, iov->iov_len, count); 147*44323Ssklower perror("due to"); 148*44323Ssklower } 149*44323Ssklower } 150*44323Ssklower if (playtag) { 151*44323Ssklower printf("Tag time!\n"); 152*44323Ssklower iov->iov_base = your_it; 153*44323Ssklower iov->iov_len = sizeof your_it; 154*44323Ssklower sendmsg(s, &msg, MSG_EOR); 155*44323Ssklower sendmsg(s, &msg, MSG_EOR); 156*44323Ssklower iov->iov_base = data_msg; 157*44323Ssklower iov->iov_len = sizeof data_msg; 158*44323Ssklower try(recvmsg, (s, &msg, flags), " playtag "); 159*44323Ssklower } 160*44323Ssklower if(nobuffs) { 161*44323Ssklower printf("looped %d times waiting for bufs\n", nobuffs); 162*44323Ssklower } 163*44323Ssklower } 164*44323Ssklower int localsize; 165*44323Ssklower char dupbuf[4096]; 166*44323Ssklower 167*44323Ssklower put_record(s, flags) 168*44323Ssklower int s, flags; 169*44323Ssklower { 170*44323Ssklower int fd, buflen; 171*44323Ssklower char *buf; 172*44323Ssklower struct sockaddr *to; 173*44323Ssklower int x, saved_x; 174*44323Ssklower 175*44323Ssklower msg.msg_flags = flags; 176*44323Ssklower if (verbose) { 177*44323Ssklower unsigned short *zp, *zlim; 178*44323Ssklower if (msg.msg_controllen) { 179*44323Ssklower zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len); 180*44323Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 181*44323Ssklower printf("CMsg data: "); 182*44323Ssklower x = msg.msg_controllen; 183*44323Ssklower zlim = zp + ((x + 1) / 2); 184*44323Ssklower while (zp < zlim) printf("%x ", *zp++); 185*44323Ssklower putchar ('\n'); 186*44323Ssklower } 187*44323Ssklower if (iov->iov_len) { 188*44323Ssklower printf("sending: %s %s", 189*44323Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""), 190*44323Ssklower (flags & MSG_EOR ? "(Record Mark)" : "")); 191*44323Ssklower x = localsize; 192*44323Ssklower zp = (unsigned short *)data_msg; 193*44323Ssklower zlim = zp + ((x + 1) / 2); 194*44323Ssklower while (zp < zlim) printf("%x ", *zp++); 195*44323Ssklower putchar ('\n'); 196*44323Ssklower } 197*44323Ssklower } 198*44323Ssklower if (verify) { 199*44323Ssklower buflen = iov->iov_len; 200*44323Ssklower bcopy(iov->iov_base, dupbuf, buflen); 201*44323Ssklower } 202*44323Ssklower try(sendmsg, (s, &msg, flags), " put_record "); 203*44323Ssklower saved_x = x; 204*44323Ssklower while (verify && buflen > 0) { 205*44323Ssklower iov->iov_len = buflen; 206*44323Ssklower iov->iov_base = dupbuf; 207*44323Ssklower try(recvmsg, (s, &msg, flags), " put_record "); 208*44323Ssklower printf("verify got %d\n", x); 209*44323Ssklower buflen -= x; 210*44323Ssklower } 211*44323Ssklower msg.msg_control = 0; 212*44323Ssklower return (saved_x); 213*44323Ssklower } 214*44323Ssklower int *datasize = &iov->iov_len; 215*44323Ssklower char *cp, *cplim; 216*44323Ssklower 217*44323Ssklower get_control_data(type) 218*44323Ssklower { 219*44323Ssklower 220*44323Ssklower datasize = (int *)&msg.msg_controllen; 221*44323Ssklower cp = cm.cm.cmdata; 222*44323Ssklower cplim = cp + sizeof(cm.cm.cmdata); 223*44323Ssklower cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 224*44323Ssklower cm.cm.cmhdr.cmsg_type = type; 225*44323Ssklower msg.msg_control = cm.data; 226*44323Ssklower } 227*44323Ssklower 228*44323Ssklower doconndata(s) 229*44323Ssklower { 230*44323Ssklower get_control_data(TPOPT_CONN_DATA); 231*44323Ssklower *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr); 232*44323Ssklower cm.cm.cmhdr.cmsg_len = *datasize; 233*44323Ssklower bcopy(conndata, cp, *datasize); 234*44323Ssklower put_record(s, 0); 235*44323Ssklower } 236*44323Ssklower 237*44323Ssklower 238*44323Ssklower 239*44323Ssklower get_record(flags) 240*44323Ssklower int *flags; 241*44323Ssklower { 242*44323Ssklower int factor = 1, x = 0; 243*44323Ssklower char workbuf[10240]; 244*44323Ssklower 245*44323Ssklower *flags = 0; 246*44323Ssklower *datasize = 0; 247*44323Ssklower datasize = &iov->iov_len; 248*44323Ssklower cp = data_msg; 249*44323Ssklower cplim = cp + sizeof(data_msg); 250*44323Ssklower 251*44323Ssklower for(;;) { 252*44323Ssklower x = scanf("%s", workbuf); 253*44323Ssklower if (x == EOF) 254*44323Ssklower break; 255*44323Ssklower if (strcmp(workbuf, "disc") == 0) 256*44323Ssklower x = get_control_data(TPOPT_DISC_DATA); 257*44323Ssklower else if (strcmp(workbuf, "cfrm") == 0) 258*44323Ssklower x = get_control_data(TPOPT_CFRM_DATA); 259*44323Ssklower else if (strcmp(workbuf, "oob") == 0) 260*44323Ssklower *flags |= MSG_OOB; 261*44323Ssklower else if (strcmp(workbuf, "eom") == 0) 262*44323Ssklower *flags |= MSG_EOR; 263*44323Ssklower else if (strcmp(workbuf, "factor") == 0) { 264*44323Ssklower x = scanf("%d", &factor); 265*44323Ssklower if (factor <= 0) factor = 1; 266*44323Ssklower if (x == EOF) 267*44323Ssklower break; 268*44323Ssklower } else { 269*44323Ssklower int len = strlen(workbuf); 270*44323Ssklower localsize = 0; 271*44323Ssklower while ((factor-- > 0) && 272*44323Ssklower ((cp + len) < cplim)) { 273*44323Ssklower strcpy(cp, workbuf); 274*44323Ssklower cp += len; 275*44323Ssklower localsize += len; 276*44323Ssklower } 277*44323Ssklower *datasize = localsize; 278*44323Ssklower if (datasize != &iov->iov_len) { 279*44323Ssklower *datasize += sizeof(cm.cm.cmhdr); 280*44323Ssklower cm.cm.cmhdr.cmsg_len = *datasize; 281*44323Ssklower } 282*44323Ssklower break; 283*44323Ssklower } 284*44323Ssklower } 285*44323Ssklower errno = 0; 286*44323Ssklower return (x); 287*44323Ssklower } 288