1*49350Ssklower /*- 245450Ssklower * Copyright (c) 1988, 1990 Regents of the University of California. 345450Ssklower * All rights reserved. 445450Ssklower * 545450Ssklower * %sccs.include.redist.c% 6*49350Ssklower * 7*49350Ssklower * @(#)xi_src.c 7.4 (Berkeley) 05/07/91 845450Ssklower */ 945450Ssklower /* 1048842Ssklower * This is a test program to be a source for X.25 connections. 1145450Ssklower */ 1245450Ssklower #include <sys/types.h> 1345450Ssklower #include <sys/socket.h> 1445450Ssklower #include <sys/uio.h> 1545450Ssklower #include <sys/ioctl.h> 1645450Ssklower #include <net/route.h> 1745450Ssklower #include <net/if.h> 1845450Ssklower #include <netccitt/x25.h> 1945450Ssklower 2045450Ssklower #include <stdio.h> 2145450Ssklower #include <errno.h> 2245450Ssklower #include <ctype.h> 2345450Ssklower #include <netdb.h> 2445450Ssklower 2545450Ssklower 2645450Ssklower #define dbprintf if(verbose)printf 2745450Ssklower #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\ 2845450Ssklower if (x < 0) {perror("a"); exit(1);}} 2945450Ssklower 3045450Ssklower fd_set readfds, writefds, exceptfds; 3145450Ssklower long size, count = 10; 3245450Ssklower int verbose = 1, selectp, type = SOCK_STREAM, nobuffs, errno, playtag = 0; 3345450Ssklower int verify = 0, mqdata; 3445450Ssklower short portnumber = 3000; 3545450Ssklower struct sockaddr_x25 to; 3645450Ssklower char your_it[] = "You're it!"; 3745450Ssklower char *port, *conndata, data_msg[2048]; 3845450Ssklower struct iovec iov[1] = {data_msg}; 3945450Ssklower union { 4045450Ssklower struct { 4145450Ssklower struct cmsghdr cmhdr; 4245450Ssklower char cmdata[128 - sizeof (struct cmsghdr)]; 4345450Ssklower } cm; 4445450Ssklower char data[128]; 4545450Ssklower } cm; 4645450Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; 4745450Ssklower 4845450Ssklower main(argc, argv) 4945450Ssklower int argc; 5045450Ssklower char *argv[]; 5145450Ssklower { 5245450Ssklower register char **av = argv; 5345450Ssklower register char *cp; 5445450Ssklower u_long len; 5545450Ssklower int handy; 5645450Ssklower 5745450Ssklower while(--argc > 0) { 5845450Ssklower av++; 5945450Ssklower if (strcmp(*av,"dest")==0) { 6045450Ssklower av++; 6145450Ssklower ccitt_addr(*av, &to); 6245450Ssklower argc--; 6345450Ssklower } else if (strcmp(*av,"count")==0) { 6445450Ssklower av++; 6545450Ssklower sscanf(*av,"%ld",&count); 6645450Ssklower argc--; 6745450Ssklower } else if (strcmp(*av,"size")==0) { 6845450Ssklower av++; 6945450Ssklower sscanf(*av,"%ld",&size); 7045450Ssklower } 7145450Ssklower } 7248842Ssklower xisrc(); 7345450Ssklower } 7445450Ssklower 7548842Ssklower xisrc() { 7645450Ssklower int x, s, pid, on = 1, flags = 8, n; 7745450Ssklower 7845450Ssklower try(socket, (AF_CCITT, type, 0),""); 7945450Ssklower s = x; 8045450Ssklower 8145450Ssklower /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/ 8245450Ssklower 8345450Ssklower to.x25_opts.op_flags |= X25_MQBIT; 8445450Ssklower try(connect, (s, (struct sockaddr *) &to, to.x25_len), ""); 8545450Ssklower 8645450Ssklower if (selectp) { 8745450Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds); 8845450Ssklower select(1, &writefds, 0, 0, 0); 8945450Ssklower } 9045450Ssklower while (count-- > 0) { 9145450Ssklower if (size <= 0 && get_record(&flags) == EOF) 9245450Ssklower exit(0); 9345450Ssklower n = put_record(s, flags); 9445450Ssklower if (n < iov->iov_len) { 9545450Ssklower if (n==-1 && errno == 55) { 9645450Ssklower nobuffs++; 9745450Ssklower count++; 9845450Ssklower continue; 9945450Ssklower } 10045450Ssklower fprintf(stderr, "wrote %d < %d, count %d,", 10145450Ssklower n, iov->iov_len, count); 10245450Ssklower perror("due to"); 10345450Ssklower } 10445450Ssklower } 10545450Ssklower if (playtag) { 10645450Ssklower printf("Tag time!\n"); 10745450Ssklower iov->iov_base = your_it; 10845450Ssklower iov->iov_len = sizeof your_it; 10945450Ssklower sendmsg(s, &msg, MSG_EOR); 11045450Ssklower sendmsg(s, &msg, MSG_EOR); 11145450Ssklower iov->iov_base = data_msg; 11245450Ssklower iov->iov_len = sizeof data_msg; 11345450Ssklower try(recvmsg, (s, &msg, flags), " playtag "); 11445450Ssklower } 11545450Ssklower if (nobuffs) { 11645450Ssklower printf("looped %d times waiting for bufs\n", nobuffs); 11745450Ssklower } 11845450Ssklower } 11945450Ssklower int localsize; 12045450Ssklower char dupbuf[4096]; 12145450Ssklower 12245450Ssklower put_record(s, flags) 12345450Ssklower int s, flags; 12445450Ssklower { 12545450Ssklower int fd, buflen; 12645450Ssklower char *buf; 12745450Ssklower int x, saved_x; 12845450Ssklower 12945450Ssklower msg.msg_flags = flags; 13045450Ssklower if (verbose) { 13145450Ssklower unsigned short *zp, *zlim; 13245450Ssklower if (msg.msg_controllen) { 13345450Ssklower zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len); 13445450Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 13545450Ssklower printf("CMsg data: "); 13645450Ssklower x = msg.msg_controllen; 13745450Ssklower zlim = zp + ((x + 1) / 2); 13845450Ssklower while (zp < zlim) printf("%x ", *zp++); 13945450Ssklower putchar ('\n'); 14045450Ssklower } 14145450Ssklower if (iov->iov_len) { 14245450Ssklower printf("sending: %s %s", 14345450Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""), 14445450Ssklower (flags & MSG_EOR ? "(Record Mark)" : "")); 14545450Ssklower x = localsize; 14645450Ssklower zp = (unsigned short *)data_msg; 14745450Ssklower zlim = zp + ((x + 1) / 2); 14845450Ssklower while (zp < zlim) printf("%x ", *zp++); 14945450Ssklower putchar ('\n'); 15045450Ssklower } 15145450Ssklower } 15245450Ssklower if (verify) { 15345450Ssklower buflen = iov->iov_len; 15445450Ssklower bcopy(iov->iov_base, dupbuf, buflen); 15545450Ssklower } 15645450Ssklower try(sendmsg, (s, &msg, flags), " put_record "); 15745450Ssklower saved_x = x; 15845450Ssklower while (verify && buflen > 0) { 15945450Ssklower iov->iov_len = buflen; 16045450Ssklower iov->iov_base = dupbuf; 16145450Ssklower try(recvmsg, (s, &msg, flags), " put_record "); 16245450Ssklower printf("verify got %d\n", x); 16345450Ssklower buflen -= x; 16445450Ssklower } 16545450Ssklower msg.msg_control = 0; 16645450Ssklower return (saved_x); 16745450Ssklower } 16845450Ssklower int *datasize = &iov->iov_len; 16945450Ssklower char *cp, *cplim; 17045450Ssklower 17145450Ssklower get_control_data(type, level) 17245450Ssklower { 17345450Ssklower 17445450Ssklower datasize = (int *)&msg.msg_controllen; 17545450Ssklower cp = cm.cm.cmdata; 17645450Ssklower cplim = cp + sizeof(cm.cm.cmdata); 17745450Ssklower cm.cm.cmhdr.cmsg_level = level; 17845450Ssklower cm.cm.cmhdr.cmsg_type = type; 17945450Ssklower msg.msg_control = cm.data; 18045450Ssklower } 18145450Ssklower 18245450Ssklower 18345450Ssklower 18445450Ssklower get_record(flags) 18545450Ssklower int *flags; 18645450Ssklower { 18745450Ssklower int factor = 1, x = 0; 18845450Ssklower char workbuf[10240]; 18948842Ssklower static repeatcount, repeatsize; 19045450Ssklower 19148842Ssklower if (repeatcount > 0) { 19248842Ssklower repeatcount--; 19348842Ssklower return; 19448842Ssklower } 19545450Ssklower *flags = 0; 19645450Ssklower *datasize = 0; 19745450Ssklower datasize = &iov->iov_len; 19845450Ssklower cp = data_msg + 1; 19945572Ssklower cplim = data_msg + sizeof(data_msg); 20045450Ssklower 20145572Ssklower *data_msg = 0; 20245450Ssklower for(;;) { 20345450Ssklower x = scanf("%s", workbuf); 20445450Ssklower if (x == EOF) 20545450Ssklower break; 20645450Ssklower if (strcmp(workbuf, "oob") == 0) 20745450Ssklower *flags |= MSG_OOB; 20845450Ssklower else if (strcmp(workbuf, "qbit") == 0) 20945450Ssklower *data_msg |= 0x80; 21045450Ssklower else if (strcmp(workbuf, "mbit") == 0) 21145450Ssklower *data_msg |= 0x40; 21245450Ssklower else if (strcmp(workbuf, "eom") == 0) 21345450Ssklower *flags |= MSG_EOR; 21445450Ssklower else if (strcmp(workbuf, "factor") == 0) { 21545450Ssklower x = scanf("%d", &factor); 21645450Ssklower if (factor <= 0) factor = 1; 21745450Ssklower if (x == EOF) 21845450Ssklower break; 21948842Ssklower } else if (strcmp(workbuf, "repeat") == 0) { 22048842Ssklower x = scanf("%d", &repeatcount); 22148842Ssklower if (repeatcount <= 0) repeatcount = 1; 22248842Ssklower if (x == EOF) 22348842Ssklower break; 22445450Ssklower } else { 22545450Ssklower int len = strlen(workbuf); 22645572Ssklower localsize = 1; 22745450Ssklower while ((factor-- > 0) && 22845450Ssklower ((cp + len) < cplim)) { 22945450Ssklower strcpy(cp, workbuf); 23045450Ssklower cp += len; 23145450Ssklower localsize += len; 23245450Ssklower } 23345450Ssklower *datasize = localsize; 23445450Ssklower if (datasize != &iov->iov_len) { 23545450Ssklower *datasize += sizeof(cm.cm.cmhdr); 23648842Ssklower repeatsize = cm.cm.cmhdr.cmsg_len = *datasize; 23745450Ssklower } 23845450Ssklower break; 23945450Ssklower } 24045450Ssklower } 24145450Ssklower errno = 0; 24245450Ssklower return (x); 24345450Ssklower } 244