149352Sbostic /*-
249352Sbostic * Copyright (c) 1988, 1990 The Regents of the University of California.
344323Ssklower * All rights reserved.
444323Ssklower *
544323Ssklower * %sccs.include.redist.c%
644323Ssklower */
749352Sbostic
844323Ssklower #ifndef lint
949352Sbostic char copyright[] =
1049352Sbostic "@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
1149352Sbostic All rights reserved.\n";
1244323Ssklower #endif /* not lint */
1344323Ssklower
1449352Sbostic #ifndef lint
15*58241Ssklower static char sccsid[] = "@(#)tisrc.c 7.8 (Berkeley) 02/25/93";
1649352Sbostic #endif /* not lint */
1749352Sbostic
1844323Ssklower /*
1948713Ssklower * This is a test program to be a source for ISO transport.
2044323Ssklower */
2144323Ssklower #include <sys/types.h>
2244323Ssklower #include <sys/socket.h>
2344323Ssklower #include <sys/uio.h>
2444323Ssklower #include <sys/ioctl.h>
2544323Ssklower #include <net/route.h>
2644323Ssklower #include <net/if.h>
2744323Ssklower #define TCPT_NTIMERS 4
2844323Ssklower #include <netiso/iso.h>
2944323Ssklower #include <netiso/tp_user.h>
3044323Ssklower
3144323Ssklower #include <stdio.h>
3244323Ssklower #include <errno.h>
3344323Ssklower #include <ctype.h>
3444323Ssklower #include <netdb.h>
3544323Ssklower
3644323Ssklower
3744323Ssklower #define dbprintf if(verbose)printf
3850891Ssklower #ifdef __STDC__
3950891Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
4050891Ssklower if (x<0) {perror(#a); exit(1);}}
4150891Ssklower #else
4250891Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
4350891Ssklower if (x<0) {perror("a");exit(1);}}
4450891Ssklower #endif
4544323Ssklower
4644323Ssklower struct iso_addr eon = {20, 0x47, 0, 6, 3, 0, 0, 0, 25 /*EGP for Berkeley*/};
4749065Ssklower struct iso_addr *iso_addr();
4844323Ssklower struct sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s;
49*58241Ssklower struct sockaddr_iso from_s = { sizeof(from_s), AF_ISO }, *from = 0;
5048713Ssklower struct sockaddr_iso old_s = { sizeof(to_s), AF_ISO }, *old = &old_s;
5148843Ssklower struct tp_conn_param tp_params;
5244323Ssklower fd_set readfds, writefds, exceptfds;
5350891Ssklower long size, count = 0;
54*58241Ssklower int verbose = 1, selectp, socktype = SOCK_SEQPACKET, nobuffs, errno, playtag = 0;
55*58241Ssklower int echop = 0, dgramp = 0, debug = 0, tp0mode = 0, dumpnodata = 0, tuba = 0;
5644323Ssklower short portnumber = 3000;
5744323Ssklower char your_it[] = "You're it!";
5850891Ssklower char *Servername, *conndata, data_msg[8192];
5948713Ssklower char Serverbuf[128];
6048713Ssklower char name[128];
6144323Ssklower struct iovec iov[1] = {data_msg};
6244323Ssklower union {
6344323Ssklower struct {
6444323Ssklower struct cmsghdr cmhdr;
6548713Ssklower char cmdata[128 - sizeof(struct cmsghdr)];
6644323Ssklower } cm;
6744323Ssklower char data[128];
6844323Ssklower } cm;
6944323Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
7044323Ssklower
main(argc,argv)7144323Ssklower main(argc, argv)
7244323Ssklower int argc;
7344323Ssklower char *argv[];
7444323Ssklower {
7544323Ssklower register char **av = argv;
7644323Ssklower register char *cp;
7744323Ssklower u_long len;
7844323Ssklower int handy;
7944323Ssklower
8044323Ssklower while(--argc > 0) {
8144323Ssklower av++;
8244323Ssklower if(strcmp(*av,"Servername")==0) {
8344323Ssklower av++;
8448713Ssklower Servername = *av;
8544323Ssklower argc--;
8644323Ssklower } else if(strcmp(*av,"conndata")==0) {
8744323Ssklower av++;
8844323Ssklower conndata = *av;
8944323Ssklower argc--;
9044323Ssklower } else if(strcmp(*av,"host")==0) {
9144323Ssklower av++;
9248713Ssklower to_s.siso_addr = *iso_addr(*av);
9344323Ssklower argc--;
94*58241Ssklower } else if(strcmp(*av,"from")==0) {
95*58241Ssklower av++;
96*58241Ssklower from_s.siso_addr = *iso_addr(*av);
97*58241Ssklower from = &from_s;
98*58241Ssklower argc--;
9944323Ssklower } else if(strcmp(*av,"port")==0) {
10044323Ssklower av++;
10144323Ssklower sscanf(*av,"%hd",&portnumber);
10244323Ssklower argc--;
10344323Ssklower } else if(strcmp(*av,"count")==0) {
10444323Ssklower av++;
10544323Ssklower sscanf(*av,"%ld",&count);
10644323Ssklower argc--;
10744323Ssklower } else if(strcmp(*av,"size")==0) {
10844323Ssklower av++;
10944323Ssklower sscanf(*av,"%ld",&size);
11044323Ssklower iov->iov_len = size;
11144323Ssklower } else if(strcmp(*av,"stream")==0) {
112*58241Ssklower socktype = SOCK_STREAM;
11350891Ssklower } else if (strcmp(*av, "echo")==0) {
11450891Ssklower echop++;
11544323Ssklower } else if (strcmp(*av,"eon") == 0) {
11644323Ssklower unsigned long l, inet_addr();
11744323Ssklower
11844323Ssklower l = inet_addr(*++av); argc--;
11944323Ssklower to_s.siso_addr = eon;
12044323Ssklower bcopy((char *)&l, &to_s.siso_data[15], 4);
12144323Ssklower }
12244323Ssklower }
12348713Ssklower maketoaddr();
12448713Ssklower tisrc();
12548713Ssklower }
12648713Ssklower
maketoaddr()12748713Ssklower maketoaddr()
12848713Ssklower {
12948713Ssklower if (Servername) {
13048713Ssklower int tlen = strlen(Servername);
13148713Ssklower int len = tlen + TSEL(to) - (caddr_t) to;
13248713Ssklower if (len < sizeof(*to)) len = sizeof(*to);
13348713Ssklower if (len > to->siso_len) {
13449065Ssklower old = to;
13544323Ssklower to = (struct sockaddr_iso *)malloc(len);
13649065Ssklower *to = *old; /* We dont care if all old tsel is copied*/
13749065Ssklower if (old != &to_s) free(old);
13844323Ssklower }
13949065Ssklower bcopy(Servername, TSEL(to), tlen);
14049065Ssklower to->siso_tlen = tlen;
14144323Ssklower } else {
14249065Ssklower to->siso_tlen = sizeof(portnumber);
14344323Ssklower portnumber = htons(portnumber);
14449065Ssklower bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber));
14544323Ssklower }
14644323Ssklower }
14744323Ssklower
tisrc()14844323Ssklower tisrc() {
149*58241Ssklower int x, s, pid, on = 1, flags = 8, n;
150*58241Ssklower int proto = (tp0mode ? ISOPROTO_TP0 : (tuba ? ISOPROTO_TCP : 0 ));
151*58241Ssklower int socktype = (dgramp ? SOCK_DGRAM :
152*58241Ssklower (tuba ? SOCK_STREAM :SOCK_SEQPACKET));
15344323Ssklower
154*58241Ssklower try(socket, (AF_ISO, socktype, proto),"");
15544323Ssklower s = x;
15644323Ssklower
15748713Ssklower if (debug)
15848713Ssklower try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof on), "");
15948713Ssklower if (dgramp == 0) {
16048713Ssklower if (conndata)
16148713Ssklower doconndata(s);
162*58241Ssklower if (from) {
163*58241Ssklower try(bind,
164*58241Ssklower (s, (struct sockaddr *)from, from->siso_len), "");
165*58241Ssklower }
16648713Ssklower try(connect, (s, (struct sockaddr *) to, to->siso_len), "");
16750891Ssklower recv_cdata(s);
16848713Ssklower }
16944323Ssklower if (selectp) {
17044323Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds);
17144323Ssklower select(1, &writefds, 0, 0, 0);
17244323Ssklower }
17350891Ssklower do {
17444323Ssklower if (size <= 0 && get_record(&flags) == EOF)
17544323Ssklower exit(0);
17644323Ssklower n = put_record(s, flags);
17744323Ssklower if (n < iov->iov_len) {
17850891Ssklower if (n == -1 && errno == 55) {
17944323Ssklower nobuffs++;
18050891Ssklower if (count) ++count;
18144323Ssklower continue;
18244323Ssklower }
18344323Ssklower fprintf(stderr, "wrote %d < %d, count %d,",
18444323Ssklower n, iov->iov_len, count);
18544323Ssklower perror("due to");
18644323Ssklower }
18750891Ssklower } while (count == 0 || --count >= 1);
18844323Ssklower if (playtag) {
18944323Ssklower printf("Tag time!\n");
19044323Ssklower iov->iov_base = your_it;
19144323Ssklower iov->iov_len = sizeof your_it;
19244323Ssklower sendmsg(s, &msg, MSG_EOR);
19344323Ssklower sendmsg(s, &msg, MSG_EOR);
19444323Ssklower iov->iov_base = data_msg;
19544323Ssklower iov->iov_len = sizeof data_msg;
19644323Ssklower try(recvmsg, (s, &msg, flags), " playtag ");
19744323Ssklower }
19844323Ssklower if(nobuffs) {
19944323Ssklower printf("looped %d times waiting for bufs\n", nobuffs);
20044323Ssklower }
20144323Ssklower }
20250891Ssklower
recv_cdata(s)20350891Ssklower recv_cdata(s)
20450891Ssklower int s;
20550891Ssklower {
20650891Ssklower int x;
20750891Ssklower iov->iov_len = 0;
20850891Ssklower msg.msg_controllen = sizeof(cm);
20950891Ssklower msg.msg_control = (char *)&cm;
21050891Ssklower try(recvmsg,(s, &msg, 0), "confirm data?");
21150891Ssklower if (msg.msg_controllen)
21250891Ssklower dumpit("", (u_short *)&cm, msg.msg_controllen);
21350891Ssklower msg.msg_control = 0;
21450891Ssklower msg.msg_controllen = 0;
21550891Ssklower }
21650891Ssklower
21744323Ssklower int localsize;
21844323Ssklower char dupbuf[4096];
21944323Ssklower
22050891Ssklower struct savebuf {
22150891Ssklower struct savebuf *s_next;
22250891Ssklower struct savebuf *s_prev;
22350891Ssklower int s_n;
22450891Ssklower int s_flags;
22550891Ssklower } savebuf = {&savebuf, &savebuf};
22650891Ssklower
22750891Ssklower void
savedata(n,flags)22850891Ssklower savedata(n, flags)
22950891Ssklower int n;
23050891Ssklower {
23150891Ssklower register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
23250891Ssklower if (s == 0)
23350891Ssklower return;
23450891Ssklower insque(s, savebuf.s_prev);
23550891Ssklower s->s_n = n;
23650891Ssklower s->s_flags = flags;
23750891Ssklower bcopy(iov->iov_base, (char *)(s + 1), n);
23850891Ssklower }
23950891Ssklower
checkback(fd)24053366Ssklower checkback(fd)
24153366Ssklower int fd;
24250891Ssklower {
24350891Ssklower int n, nn;
24450891Ssklower register struct savebuf *s = savebuf.s_next, *t;
24550891Ssklower register char *cp = data_msg;
24650891Ssklower while (s != &savebuf) {
24750891Ssklower nn = s->s_n;
24850891Ssklower do {
24950891Ssklower msg.msg_flags = 0;
25050891Ssklower iov->iov_len = nn;
25150891Ssklower iov->iov_base = cp;
25253366Ssklower n = recvmsg(fd, &msg, 0);
25350891Ssklower cp += n;
25450891Ssklower nn -= n;
25550891Ssklower } while (dgramp == 0 && nn > 0 && !(msg.msg_flags & MSG_EOR));
25650891Ssklower iov->iov_base = data_msg;
25750891Ssklower if (dgramp) {
25850891Ssklower if (msg.msg_namelen)
25950891Ssklower dumpit("from: ", to, msg.msg_namelen);
26050891Ssklower msg.msg_namelen = old->siso_len;
26150891Ssklower }
26250891Ssklower n = s->s_n - nn;
26350891Ssklower dbprintf("echoed %d", n);
26450891Ssklower if (nn)
26550891Ssklower dbprintf(" instead of %d", s->s_n);
26650891Ssklower if (bcmp((char *)(s + 1), data_msg, n))
26750891Ssklower dbprintf(", with mismatched data");
26850891Ssklower if (nn && (msg.msg_flags & MSG_EOR))
26950891Ssklower dbprintf(" and with %d unchecked after EOR", nn);
27050891Ssklower dbprintf("\n");
27150891Ssklower t = s; s = s->s_next; remque(t); free((char *)t);
27250891Ssklower }
27350891Ssklower }
27450891Ssklower
27550891Ssklower
put_record(s,flags)27644323Ssklower put_record(s, flags)
27744323Ssklower int s, flags;
27844323Ssklower {
27944323Ssklower char *buf;
28044323Ssklower int x, saved_x;
28144323Ssklower
28244323Ssklower msg.msg_flags = flags;
28344323Ssklower if (verbose) {
28444323Ssklower if (msg.msg_controllen) {
28544323Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
28648713Ssklower dumpit("CMsg data:\n", &msg.msg_control, msg.msg_controllen);
28744323Ssklower }
28844323Ssklower if (iov->iov_len) {
28944323Ssklower printf("sending: %s %s",
29044323Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""),
29144323Ssklower (flags & MSG_EOR ? "(Record Mark)" : ""));
29248713Ssklower dumpit("data: ", data_msg, localsize);
29344323Ssklower }
29444323Ssklower }
29550891Ssklower if (echop)
29650891Ssklower savedata(iov->iov_len, flags);
29748713Ssklower if (dgramp) {
29848713Ssklower msg.msg_name = (caddr_t)to;
29948713Ssklower msg.msg_namelen = to->siso_len;
30048713Ssklower }
30144323Ssklower try(sendmsg, (s, &msg, flags), " put_record ");
30244323Ssklower saved_x = x;
30350891Ssklower if (echop && (flags & MSG_EOR))
30450891Ssklower checkback(s);
30548713Ssklower bcopy(old, to, old->siso_len);
30644323Ssklower msg.msg_control = 0;
30744323Ssklower return (saved_x);
30844323Ssklower }
dumpit(what,where,n)30948713Ssklower dumpit(what, where, n)
31048713Ssklower char *what; unsigned short *where; int n;
31148713Ssklower {
31248713Ssklower unsigned short *s = where;
31348713Ssklower unsigned short *z = where + (n+1)/2;
31448713Ssklower int count = 0;
31550891Ssklower if (dumpnodata)
31648713Ssklower return;
31748713Ssklower printf(what);
31848713Ssklower while(s < z) {
31948713Ssklower count++;
32048713Ssklower printf("%x ",*s++);
32148713Ssklower if ((count & 15) == 0)
32248713Ssklower putchar('\n');
32348713Ssklower }
32448713Ssklower if (count & 15)
32548713Ssklower putchar('\n');
32648713Ssklower fflush(stdout);
32748713Ssklower }
32844323Ssklower int *datasize = &iov->iov_len;
32944323Ssklower char *cp, *cplim;
33044323Ssklower
get_control_data(type)33144323Ssklower get_control_data(type)
33244323Ssklower {
33344323Ssklower
33444323Ssklower datasize = (int *)&msg.msg_controllen;
33544323Ssklower cp = cm.cm.cmdata;
33644323Ssklower cplim = cp + sizeof(cm.cm.cmdata);
33744323Ssklower cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT;
33844323Ssklower cm.cm.cmhdr.cmsg_type = type;
33944323Ssklower msg.msg_control = cm.data;
34044323Ssklower }
34144323Ssklower
doconndata(s)34244323Ssklower doconndata(s)
34344323Ssklower {
34444323Ssklower get_control_data(TPOPT_CONN_DATA);
34544323Ssklower *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr);
34644323Ssklower cm.cm.cmhdr.cmsg_len = *datasize;
34744323Ssklower bcopy(conndata, cp, *datasize);
34844323Ssklower put_record(s, 0);
34944323Ssklower }
35044323Ssklower
get_altbuf(addrbuf)35148713Ssklower get_altbuf(addrbuf)
35248713Ssklower char *addrbuf;
35348713Ssklower {
35448713Ssklower if (dgramp == 0) {
35548713Ssklower printf("illegal option for stream\n");
35648713Ssklower return 1;
35748713Ssklower }
35848713Ssklower return (scanf("%s", addrbuf) == EOF ? 1 : 0);
35948713Ssklower }
36044323Ssklower
get_record(flags)36144323Ssklower get_record(flags)
36244323Ssklower int *flags;
36344323Ssklower {
36448713Ssklower int factor = 1, x = 0, newaddr = 0;
36548713Ssklower static repeatcount, repeatsize;
36644323Ssklower char workbuf[10240];
36748713Ssklower char addrbuf[128];
36844323Ssklower
36948713Ssklower if (repeatcount > 0) {
37048713Ssklower repeatcount--;
37148713Ssklower return;
37248713Ssklower }
37348713Ssklower
37444323Ssklower *flags = 0;
37544323Ssklower *datasize = 0;
37644323Ssklower datasize = &iov->iov_len;
37744323Ssklower cp = data_msg;
37844323Ssklower cplim = cp + sizeof(data_msg);
37944323Ssklower
38044323Ssklower for(;;) {
38144323Ssklower x = scanf("%s", workbuf);
38244323Ssklower if (x == EOF)
38344323Ssklower break;
38448713Ssklower if (strcmp(workbuf, "host") == 0) {
38548713Ssklower if (get_altbuf(addrbuf))
38648713Ssklower break;
38748713Ssklower to->siso_addr = *iso_addr(addrbuf);
38848713Ssklower newaddr = 1;
38948713Ssklower } else if (strcmp(workbuf, "Servername") == 0) {
39048713Ssklower if (get_altbuf(Serverbuf))
39148713Ssklower break;
39248713Ssklower Servername = Serverbuf;
39348713Ssklower newaddr = 1;
39448713Ssklower } else if (strcmp(workbuf, "port") == 0) {
39548713Ssklower x = scanf("%hd", &portnumber);
39648713Ssklower if (x == EOF)
39748713Ssklower break;
39848713Ssklower Servername = 0;
39948713Ssklower newaddr = 1;
40048713Ssklower } else if (strcmp(workbuf, "repeat") == 0) {
40148713Ssklower x = scanf("%d", &repeatcount);
40248713Ssklower if (repeatcount <= 0) repeatcount = 1;
40348713Ssklower repeatcount--;
40448713Ssklower if (x == EOF)
40548713Ssklower break;
40648713Ssklower } else if (strcmp(workbuf, "disc") == 0)
40744323Ssklower x = get_control_data(TPOPT_DISC_DATA);
40844323Ssklower else if (strcmp(workbuf, "cfrm") == 0)
40944323Ssklower x = get_control_data(TPOPT_CFRM_DATA);
41044323Ssklower else if (strcmp(workbuf, "oob") == 0)
41144323Ssklower *flags |= MSG_OOB;
41244323Ssklower else if (strcmp(workbuf, "eom") == 0)
41344323Ssklower *flags |= MSG_EOR;
41444323Ssklower else if (strcmp(workbuf, "factor") == 0) {
41544323Ssklower x = scanf("%d", &factor);
41644323Ssklower if (factor <= 0) factor = 1;
41744323Ssklower if (x == EOF)
41844323Ssklower break;
41944323Ssklower } else {
42044323Ssklower int len = strlen(workbuf);
42144323Ssklower localsize = 0;
42244323Ssklower while ((factor-- > 0) &&
42344323Ssklower ((cp + len) < cplim)) {
42444323Ssklower strcpy(cp, workbuf);
42544323Ssklower cp += len;
42644323Ssklower localsize += len;
42744323Ssklower }
42844323Ssklower *datasize = localsize;
42944323Ssklower if (datasize != &iov->iov_len) {
43044323Ssklower *datasize += sizeof(cm.cm.cmhdr);
43148713Ssklower repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
43244323Ssklower }
43344323Ssklower break;
43444323Ssklower }
43544323Ssklower }
43644323Ssklower errno = 0;
43748713Ssklower if (newaddr)
43848713Ssklower maketoaddr();
43944323Ssklower return (x);
44044323Ssklower }
441