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.6 (Berkeley) 07/15/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 #ifdef __STDC__ 37 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\ 38 if(x<0) {perror(#a); exit(1);}} 39 #else 40 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\ 41 if(x<0) {perror("a"); exit(1);}} 42 #endif 43 44 fd_set readfds, writefds, exceptfds; 45 long size, count = 10; 46 int verbose = 1, selectp, type = SOCK_STREAM, nobuffs, errno, playtag = 0; 47 int verify = 0, mqdata, protolisten = 0, echop = 0; 48 unsigned char protodata[2] = {0, 1}; 49 short portnumber = 3000; 50 struct sockaddr_x25 to; 51 char your_it[] = "You're it!"; 52 char *port, *conndata, data_msg[2048]; 53 struct iovec iov[1] = {data_msg}; 54 union { 55 struct { 56 struct cmsghdr cmhdr; 57 char cmdata[128 - sizeof (struct cmsghdr)]; 58 } cm; 59 char data[128]; 60 } cm; 61 struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; 62 63 main(argc, argv) 64 int argc; 65 char *argv[]; 66 { 67 register char **av = argv; 68 register char *cp; 69 u_long len; 70 int handy; 71 72 while(--argc > 0) { 73 av++; 74 if (strcmp(*av,"dest")==0) { 75 av++; 76 ccitt_addr(*av, &to); 77 argc--; 78 } else if (strcmp(*av,"count")==0) { 79 av++; 80 sscanf(*av,"%ld",&count); 81 argc--; 82 } else if (strcmp(*av,"size")==0) { 83 av++; 84 sscanf(*av,"%ld",&size); 85 argc--; 86 } else if (strcmp(*av,"protolisten")==0) { 87 av++; 88 protolisten = 1; 89 sscanf(*av,"%ld",&handy); 90 argc--; 91 protodata[0] = handy; 92 } else if (strcmp(*av,"protonolisten")==0) { 93 av++; 94 protolisten = 1; 95 sscanf(*av,"%ld",&handy); 96 argc--; 97 protodata[0] = handy; 98 protodata[1] = 0; 99 } 100 } 101 xisrc(); 102 } 103 104 xisrc() { 105 int x, s, pid, on = 1, flags = 8, n; 106 107 try(socket, (AF_CCITT, type, 0),""); 108 s = x; 109 110 /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/ 111 112 if (protolisten) { 113 try(setsockopt, (s, CCITTPROTO_X25, PK_PRLISTEN, 114 protodata, sizeof (protodata)), ""); 115 exit(0); 116 } 117 118 to.x25_opts.op_flags |= X25_MQBIT; 119 try(connect, (s, (struct sockaddr *) &to, to.x25_len), ""); 120 121 if (selectp) { 122 FD_ZERO(&writefds); FD_SET(s, &writefds); 123 select(1, &writefds, 0, 0, 0); 124 } 125 while (count-- > 0) { 126 if (size <= 0 && get_record(&flags) == EOF) 127 exit(0); 128 n = put_record(s, flags); 129 if (n < iov->iov_len) { 130 if (n==-1 && errno == 55) { 131 nobuffs++; 132 count++; 133 continue; 134 } 135 fprintf(stderr, "wrote %d < %d, count %d,", 136 n, iov->iov_len, count); 137 perror("due to"); 138 } 139 } 140 if (playtag) { 141 printf("Tag time!\n"); 142 iov->iov_base = your_it; 143 iov->iov_len = sizeof your_it; 144 sendmsg(s, &msg, MSG_EOR); 145 sendmsg(s, &msg, MSG_EOR); 146 iov->iov_base = data_msg; 147 iov->iov_len = sizeof data_msg; 148 try(recvmsg, (s, &msg, flags), " playtag "); 149 } 150 if (nobuffs) { 151 printf("looped %d times waiting for bufs\n", nobuffs); 152 } 153 } 154 int localsize; 155 char dupbuf[4096]; 156 157 struct savebuf { 158 struct savebuf *s_next; 159 struct savebuf *s_prev; 160 int s_n; 161 int s_flags; 162 } savebuf = {&savebuf, &savebuf}; 163 164 void 165 savedata(n, flags) 166 int n; 167 { 168 register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s); 169 if (s == 0) 170 return; 171 insque(s, savebuf.s_prev); 172 s->s_n = n; 173 s->s_flags = flags; 174 if (verify) 175 bcopy(iov->iov_base, (char *)(s + 1), n); 176 } 177 178 checkback(ns) 179 int ns; 180 { 181 int n; 182 register struct savebuf *s = savebuf.s_next, *t; 183 while (s != &savebuf) { 184 iov->iov_len = s->s_n; 185 n = recvmsg(ns, &msg, s->s_flags); 186 dbprintf("echoed %d\n", n); 187 if (verify && 188 (n != s->s_n || bcmp((char *)(s + 1), iov->iov_base, n))) 189 dbprintf("mismatched data or length was %d got %d\n", 190 s->s_n, n); 191 t = s; s = s->s_next; remque(t); free((char *)t); 192 } 193 } 194 195 put_record(s, flags) 196 int s, flags; 197 { 198 int fd, buflen; 199 char *buf; 200 int x, saved_x; 201 202 msg.msg_flags = flags; 203 if (verbose) { 204 unsigned short *zp, *zlim; 205 if (msg.msg_controllen) { 206 zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len); 207 printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 208 printf("CMsg data: "); 209 x = msg.msg_controllen; 210 zlim = zp + ((x + 1) / 2); 211 while (zp < zlim) printf("%x ", *zp++); 212 putchar ('\n'); 213 } 214 if (iov->iov_len) { 215 printf("sending: %s %s", 216 (flags & MSG_OOB ? "(OOB Data)" : ""), 217 (flags & MSG_EOR ? "(Record Mark)" : "")); 218 x = localsize; 219 zp = (unsigned short *)data_msg; 220 zlim = zp + ((x + 1) / 2); 221 while (zp < zlim) printf("%x ", *zp++); 222 putchar ('\n'); 223 } 224 } 225 if (echop) 226 savedata(iov->iov_len, flags); 227 try(sendmsg, (s, &msg, flags), " put_record "); 228 saved_x = x; 229 if (echop && (iov->iov_base[0] & 0x80)) 230 checkback(s); 231 msg.msg_control = 0; 232 return (saved_x); 233 } 234 int *datasize = &iov->iov_len; 235 char *cp, *cplim; 236 237 get_control_data(type, level) 238 { 239 240 datasize = (int *)&msg.msg_controllen; 241 cp = cm.cm.cmdata; 242 cplim = cp + sizeof(cm.cm.cmdata); 243 cm.cm.cmhdr.cmsg_level = level; 244 cm.cm.cmhdr.cmsg_type = type; 245 msg.msg_control = cm.data; 246 } 247 248 249 250 get_record(flags) 251 int *flags; 252 { 253 int factor = 1, x = 0; 254 char workbuf[10240]; 255 static repeatcount, repeatsize; 256 257 if (repeatcount > 0) { 258 repeatcount--; 259 return; 260 } 261 *flags = 0; 262 *datasize = 0; 263 datasize = &iov->iov_len; 264 cp = data_msg + 1; 265 cplim = data_msg + sizeof(data_msg); 266 267 *data_msg = 0; 268 for(;;) { 269 x = scanf("%s", workbuf); 270 if (x == EOF) 271 break; 272 if (strcmp(workbuf, "oob") == 0) 273 *flags |= MSG_OOB; 274 else if (strcmp(workbuf, "qbit") == 0) 275 *data_msg |= 0x80; 276 else if (strcmp(workbuf, "mbit") == 0) 277 *data_msg |= 0x40; 278 else if (strcmp(workbuf, "eom") == 0) 279 *flags |= MSG_EOR; 280 else if (strcmp(workbuf, "factor") == 0) { 281 x = scanf("%d", &factor); 282 if (factor <= 0) factor = 1; 283 if (x == EOF) 284 break; 285 } else if (strcmp(workbuf, "repeat") == 0) { 286 x = scanf("%d", &repeatcount); 287 if (repeatcount <= 0) repeatcount = 1; 288 if (x == EOF) 289 break; 290 } else { 291 int len = strlen(workbuf); 292 localsize = 1; 293 while ((factor-- > 0) && 294 ((cp + len) < cplim)) { 295 strcpy(cp, workbuf); 296 cp += len; 297 localsize += len; 298 } 299 *datasize = localsize; 300 if (datasize != &iov->iov_len) { 301 *datasize += sizeof(cm.cm.cmhdr); 302 repeatsize = cm.cm.cmhdr.cmsg_len = *datasize; 303 } 304 break; 305 } 306 } 307 errno = 0; 308 return (x); 309 } 310