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