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