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