1 /* 2 * Copyright (c) 1989, 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[] = "@(#)tisrc.c 7.3 (Berkeley) 04/29/91"; 9 #endif /* not lint */ 10 11 /* 12 * This is a test program to be a source for ISO transport. 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 #define TCPT_NTIMERS 4 21 #include <netiso/iso.h> 22 #include <netiso/tp_user.h> 23 24 #include <stdio.h> 25 #include <errno.h> 26 #include <ctype.h> 27 #include <netdb.h> 28 29 30 #define dbprintf if(verbose)printf 31 #define try(a,b,c) {x = (a b);dbprintf("%s%s returns %d\n",c,"a",x);\ 32 if (x < 0) {perror("a"); exit(1);}} 33 34 struct iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/}; 35 struct sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s; 36 struct sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s; 37 struct tp_conn_param tp_params; 38 fd_set readfds, writefds, exceptfds; 39 long size, count = 10; 40 int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0; 41 int verify = 0, dgramp = 0, debug = 0, tp0mode = 1; 42 short portnumber = 3000; 43 char your_it[] = "You're it!"; 44 char *Servername, *conndata, data_msg[2048]; 45 char Serverbuf[128]; 46 char name[128]; 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,"Servername")==0) { 69 av++; 70 Servername = *av; 71 argc--; 72 } else if(strcmp(*av,"conndata")==0) { 73 av++; 74 conndata = *av; 75 argc--; 76 } else if(strcmp(*av,"host")==0) { 77 av++; 78 to_s.siso_addr = *iso_addr(*av); 79 argc--; 80 } else if(strcmp(*av,"port")==0) { 81 av++; 82 sscanf(*av,"%hd",&portnumber); 83 argc--; 84 } else if(strcmp(*av,"count")==0) { 85 av++; 86 sscanf(*av,"%ld",&count); 87 argc--; 88 } else if(strcmp(*av,"size")==0) { 89 av++; 90 sscanf(*av,"%ld",&size); 91 iov->iov_len = size; 92 } else if(strcmp(*av,"stream")==0) { 93 type = SOCK_STREAM; 94 } else if (strcmp(*av,"eon") == 0) { 95 unsigned long l, inet_addr(); 96 97 l = inet_addr(*++av); argc--; 98 to_s.siso_addr = eon; 99 bcopy((char *)&l, &to_s.siso_data[15], 4); 100 } 101 } 102 maketoaddr(); 103 tisrc(); 104 } 105 106 maketoaddr() 107 { 108 if (Servername) { 109 int tlen = strlen(Servername); 110 int len = tlen + TSEL(to) - (caddr_t) to; 111 if (len < sizeof(*to)) len = sizeof(*to); 112 if (len > to->siso_len) { 113 if (old != &old_s) free(old); 114 old = (struct sockaddr_iso *)malloc(len); 115 *old = *to; /* We dont care if all old tsel is copied*/ 116 old->siso_len = len; 117 if (to != &to_s) free(to); 118 to = (struct sockaddr_iso *)malloc(len); 119 } 120 bcopy(Servername, TSEL(old), tlen); 121 } else { 122 old->siso_tlen = sizeof(portnumber); 123 portnumber = htons(portnumber); 124 bcopy((char *)&portnumber, TSEL(old), sizeof(portnumber)); 125 } 126 bcopy(old, to, old->siso_len); 127 } 128 129 tisrc() { 130 int x, s, pid, on = 1, flags = 8, n, proto = tp0mode ? ISOPROTO_TP0: 0; 131 132 if (dgramp) type = SOCK_DGRAM; 133 try(socket, (AF_ISO, type, proto),""); 134 s = x; 135 136 if (debug) 137 try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), ""); 138 if (dgramp == 0) { 139 if (conndata) 140 doconndata(s); 141 try(connect, (s, (struct sockaddr *) to, to->siso_len), ""); 142 } 143 if (selectp) { 144 FD_ZERO(&writefds); FD_SET(s, &writefds); 145 select(1, &writefds, 0, 0, 0); 146 } 147 while (count-- > 0) { 148 if (size <= 0 && get_record(&flags) == EOF) 149 exit(0); 150 n = put_record(s, flags); 151 if (n < iov->iov_len) { 152 if (n==-1 && errno == 55) { 153 nobuffs++; 154 count++; 155 continue; 156 } 157 fprintf(stderr, "wrote %d < %d, count %d,", 158 n, iov->iov_len, count); 159 perror("due to"); 160 } 161 } 162 if (playtag) { 163 printf("Tag time!\n"); 164 iov->iov_base = your_it; 165 iov->iov_len = sizeof your_it; 166 sendmsg(s, &msg, MSG_EOR); 167 sendmsg(s, &msg, MSG_EOR); 168 iov->iov_base = data_msg; 169 iov->iov_len = sizeof data_msg; 170 try(recvmsg, (s, &msg, flags), " playtag "); 171 } 172 if(nobuffs) { 173 printf("looped %d times waiting for bufs\n", nobuffs); 174 } 175 } 176 int localsize; 177 char dupbuf[4096]; 178 179 put_record(s, flags) 180 int s, flags; 181 { 182 int fd, buflen; 183 char *buf; 184 int x, saved_x; 185 186 msg.msg_flags = flags; 187 if (verbose) { 188 if (msg.msg_controllen) { 189 printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); 190 dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen); 191 } 192 if (iov->iov_len) { 193 printf("sending: %s %s", 194 (flags & MSG_OOB ? "(OOB Data)" : ""), 195 (flags & MSG_EOR ? "(Record Mark)" : "")); 196 dumpit("data: ", data_msg, localsize); 197 } 198 } 199 if (verify) { 200 buflen = iov->iov_len; 201 bcopy(iov->iov_base, dupbuf, buflen); 202 } 203 if (dgramp) { 204 msg.msg_name = (caddr_t)to; 205 msg.msg_namelen = to->siso_len; 206 } 207 try(sendmsg, (s, &msg, flags), " put_record "); 208 saved_x = x; 209 while (verify && buflen > 0) { 210 iov->iov_len = buflen; 211 iov->iov_base = dupbuf; 212 try(recvmsg, (s, &msg, flags), " put_record "); 213 if (dgramp) { 214 if (msg.msg_namelen) 215 dumpit("from: ", to, msg.msg_namelen); 216 msg.msg_namelen = old->siso_len; 217 } 218 printf("verify got %d\n", x); 219 buflen -= x; 220 } 221 bcopy(old, to, old->siso_len); 222 msg.msg_control = 0; 223 return (saved_x); 224 } 225 dumpit(what, where, n) 226 char *what; unsigned short *where; int n; 227 { 228 unsigned short *s = where; 229 unsigned short *z = where + (n+1)/2; 230 int count = 0; 231 if (verbose == 0) 232 return; 233 printf(what); 234 while(s < z) { 235 count++; 236 printf("%x ",*s++); 237 if ((count & 15) == 0) 238 putchar('\n'); 239 } 240 if (count & 15) 241 putchar('\n'); 242 fflush(stdout); 243 } 244 int *datasize = &iov->iov_len; 245 char *cp, *cplim; 246 247 get_control_data(type) 248 { 249 250 datasize = (int *)&msg.msg_controllen; 251 cp = cm.cm.cmdata; 252 cplim = cp + sizeof(cm.cm.cmdata); 253 cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT; 254 cm.cm.cmhdr.cmsg_type = type; 255 msg.msg_control = cm.data; 256 } 257 258 doconndata(s) 259 { 260 get_control_data(TPOPT_CONN_DATA); 261 *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr); 262 cm.cm.cmhdr.cmsg_len = *datasize; 263 bcopy(conndata, cp, *datasize); 264 put_record(s, 0); 265 } 266 267 get_altbuf(addrbuf) 268 char *addrbuf; 269 { 270 if (dgramp == 0) { 271 printf("illegal option for stream\n"); 272 return 1; 273 } 274 return (scanf("%s", addrbuf) == EOF ? 1 : 0); 275 } 276 277 get_record(flags) 278 int *flags; 279 { 280 int factor = 1, x = 0, newaddr = 0; 281 static repeatcount, repeatsize; 282 char workbuf[10240]; 283 char addrbuf[128]; 284 285 if (repeatcount > 0) { 286 repeatcount--; 287 return; 288 } 289 290 *flags = 0; 291 *datasize = 0; 292 datasize = &iov->iov_len; 293 cp = data_msg; 294 cplim = cp + sizeof(data_msg); 295 296 for(;;) { 297 x = scanf("%s", workbuf); 298 if (x == EOF) 299 break; 300 if (strcmp(workbuf, "host") == 0) { 301 if (get_altbuf(addrbuf)) 302 break; 303 to->siso_addr = *iso_addr(addrbuf); 304 newaddr = 1; 305 } else if (strcmp(workbuf, "Servername") == 0) { 306 if (get_altbuf(Serverbuf)) 307 break; 308 Servername = Serverbuf; 309 newaddr = 1; 310 } else if (strcmp(workbuf, "port") == 0) { 311 x = scanf("%hd", &portnumber); 312 if (x == EOF) 313 break; 314 Servername = 0; 315 newaddr = 1; 316 } else if (strcmp(workbuf, "repeat") == 0) { 317 x = scanf("%d", &repeatcount); 318 if (repeatcount <= 0) repeatcount = 1; 319 repeatcount--; 320 if (x == EOF) 321 break; 322 } else if (strcmp(workbuf, "disc") == 0) 323 x = get_control_data(TPOPT_DISC_DATA); 324 else if (strcmp(workbuf, "cfrm") == 0) 325 x = get_control_data(TPOPT_CFRM_DATA); 326 else if (strcmp(workbuf, "oob") == 0) 327 *flags |= MSG_OOB; 328 else if (strcmp(workbuf, "eom") == 0) 329 *flags |= MSG_EOR; 330 else if (strcmp(workbuf, "factor") == 0) { 331 x = scanf("%d", &factor); 332 if (factor <= 0) factor = 1; 333 if (x == EOF) 334 break; 335 } else { 336 int len = strlen(workbuf); 337 localsize = 0; 338 while ((factor-- > 0) && 339 ((cp + len) < cplim)) { 340 strcpy(cp, workbuf); 341 cp += len; 342 localsize += len; 343 } 344 *datasize = localsize; 345 if (datasize != &iov->iov_len) { 346 *datasize += sizeof(cm.cm.cmhdr); 347 repeatsize = cm.cm.cmhdr.cmsg_len = *datasize; 348 } 349 break; 350 } 351 } 352 errno = 0; 353 if (newaddr) 354 maketoaddr(); 355 return (x); 356 } 357