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