149350Ssklower /*-
249353Sbostic * Copyright (c) 1988, 1991 The Regents of the University of California.
345450Ssklower * All rights reserved.
445450Ssklower *
545450Ssklower * %sccs.include.redist.c%
645450Ssklower */
749353Sbostic
849353Sbostic #ifndef lint
949353Sbostic char copyright[] =
1049353Sbostic "@(#) Copyright (c) 1988, 1991 The Regents of the University of California.\n\
1149353Sbostic All rights reserved.\n";
1249353Sbostic #endif /* not lint */
1349353Sbostic
1449353Sbostic #ifndef lint
15*50424Ssklower static char sccsid[] = "@(#)xi_src.c 7.6 (Berkeley) 07/15/91";
1649353Sbostic #endif /* not lint */
1749353Sbostic
1845450Ssklower /*
1948842Ssklower * This is a test program to be a source for X.25 connections.
2045450Ssklower */
2145450Ssklower #include <sys/types.h>
2245450Ssklower #include <sys/socket.h>
2345450Ssklower #include <sys/uio.h>
2445450Ssklower #include <sys/ioctl.h>
2545450Ssklower #include <net/route.h>
2645450Ssklower #include <net/if.h>
2745450Ssklower #include <netccitt/x25.h>
2845450Ssklower
2945450Ssklower #include <stdio.h>
3045450Ssklower #include <errno.h>
3145450Ssklower #include <ctype.h>
3245450Ssklower #include <netdb.h>
3345450Ssklower
3445450Ssklower
3545450Ssklower #define dbprintf if(verbose)printf
36*50424Ssklower #ifdef __STDC__
37*50424Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
38*50424Ssklower if(x<0) {perror(#a); exit(1);}}
39*50424Ssklower #else
40*50424Ssklower #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
41*50424Ssklower if(x<0) {perror("a"); exit(1);}}
42*50424Ssklower #endif
4345450Ssklower
4445450Ssklower fd_set readfds, writefds, exceptfds;
4545450Ssklower long size, count = 10;
4645450Ssklower int verbose = 1, selectp, type = SOCK_STREAM, nobuffs, errno, playtag = 0;
47*50424Ssklower int verify = 0, mqdata, protolisten = 0, echop = 0;
48*50424Ssklower unsigned char protodata[2] = {0, 1};
4945450Ssklower short portnumber = 3000;
5045450Ssklower struct sockaddr_x25 to;
5145450Ssklower char your_it[] = "You're it!";
5245450Ssklower char *port, *conndata, data_msg[2048];
5345450Ssklower struct iovec iov[1] = {data_msg};
5445450Ssklower union {
5545450Ssklower struct {
5645450Ssklower struct cmsghdr cmhdr;
5745450Ssklower char cmdata[128 - sizeof (struct cmsghdr)];
5845450Ssklower } cm;
5945450Ssklower char data[128];
6045450Ssklower } cm;
6145450Ssklower struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
6245450Ssklower
main(argc,argv)6345450Ssklower main(argc, argv)
6445450Ssklower int argc;
6545450Ssklower char *argv[];
6645450Ssklower {
6745450Ssklower register char **av = argv;
6845450Ssklower register char *cp;
6945450Ssklower u_long len;
7045450Ssklower int handy;
7145450Ssklower
7245450Ssklower while(--argc > 0) {
7345450Ssklower av++;
7445450Ssklower if (strcmp(*av,"dest")==0) {
7545450Ssklower av++;
7645450Ssklower ccitt_addr(*av, &to);
7745450Ssklower argc--;
7845450Ssklower } else if (strcmp(*av,"count")==0) {
7945450Ssklower av++;
8045450Ssklower sscanf(*av,"%ld",&count);
8145450Ssklower argc--;
8245450Ssklower } else if (strcmp(*av,"size")==0) {
8345450Ssklower av++;
8445450Ssklower sscanf(*av,"%ld",&size);
85*50424Ssklower argc--;
86*50424Ssklower } else if (strcmp(*av,"protolisten")==0) {
87*50424Ssklower av++;
88*50424Ssklower protolisten = 1;
89*50424Ssklower sscanf(*av,"%ld",&handy);
90*50424Ssklower argc--;
91*50424Ssklower protodata[0] = handy;
92*50424Ssklower } else if (strcmp(*av,"protonolisten")==0) {
93*50424Ssklower av++;
94*50424Ssklower protolisten = 1;
95*50424Ssklower sscanf(*av,"%ld",&handy);
96*50424Ssklower argc--;
97*50424Ssklower protodata[0] = handy;
98*50424Ssklower protodata[1] = 0;
99*50424Ssklower }
10045450Ssklower }
10148842Ssklower xisrc();
10245450Ssklower }
10345450Ssklower
xisrc()10448842Ssklower xisrc() {
10545450Ssklower int x, s, pid, on = 1, flags = 8, n;
10645450Ssklower
10745450Ssklower try(socket, (AF_CCITT, type, 0),"");
10845450Ssklower s = x;
10945450Ssklower
11045450Ssklower /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/
11145450Ssklower
112*50424Ssklower if (protolisten) {
113*50424Ssklower try(setsockopt, (s, CCITTPROTO_X25, PK_PRLISTEN,
114*50424Ssklower protodata, sizeof (protodata)), "");
115*50424Ssklower exit(0);
116*50424Ssklower }
117*50424Ssklower
11845450Ssklower to.x25_opts.op_flags |= X25_MQBIT;
11945450Ssklower try(connect, (s, (struct sockaddr *) &to, to.x25_len), "");
12045450Ssklower
12145450Ssklower if (selectp) {
12245450Ssklower FD_ZERO(&writefds); FD_SET(s, &writefds);
12345450Ssklower select(1, &writefds, 0, 0, 0);
12445450Ssklower }
12545450Ssklower while (count-- > 0) {
12645450Ssklower if (size <= 0 && get_record(&flags) == EOF)
12745450Ssklower exit(0);
12845450Ssklower n = put_record(s, flags);
12945450Ssklower if (n < iov->iov_len) {
13045450Ssklower if (n==-1 && errno == 55) {
13145450Ssklower nobuffs++;
13245450Ssklower count++;
13345450Ssklower continue;
13445450Ssklower }
13545450Ssklower fprintf(stderr, "wrote %d < %d, count %d,",
13645450Ssklower n, iov->iov_len, count);
13745450Ssklower perror("due to");
13845450Ssklower }
13945450Ssklower }
14045450Ssklower if (playtag) {
14145450Ssklower printf("Tag time!\n");
14245450Ssklower iov->iov_base = your_it;
14345450Ssklower iov->iov_len = sizeof your_it;
14445450Ssklower sendmsg(s, &msg, MSG_EOR);
14545450Ssklower sendmsg(s, &msg, MSG_EOR);
14645450Ssklower iov->iov_base = data_msg;
14745450Ssklower iov->iov_len = sizeof data_msg;
14845450Ssklower try(recvmsg, (s, &msg, flags), " playtag ");
14945450Ssklower }
15045450Ssklower if (nobuffs) {
15145450Ssklower printf("looped %d times waiting for bufs\n", nobuffs);
15245450Ssklower }
15345450Ssklower }
15445450Ssklower int localsize;
15545450Ssklower char dupbuf[4096];
15645450Ssklower
157*50424Ssklower struct savebuf {
158*50424Ssklower struct savebuf *s_next;
159*50424Ssklower struct savebuf *s_prev;
160*50424Ssklower int s_n;
161*50424Ssklower int s_flags;
162*50424Ssklower } savebuf = {&savebuf, &savebuf};
163*50424Ssklower
164*50424Ssklower void
savedata(n,flags)165*50424Ssklower savedata(n, flags)
166*50424Ssklower int n;
167*50424Ssklower {
168*50424Ssklower register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
169*50424Ssklower if (s == 0)
170*50424Ssklower return;
171*50424Ssklower insque(s, savebuf.s_prev);
172*50424Ssklower s->s_n = n;
173*50424Ssklower s->s_flags = flags;
174*50424Ssklower if (verify)
175*50424Ssklower bcopy(iov->iov_base, (char *)(s + 1), n);
176*50424Ssklower }
177*50424Ssklower
checkback(ns)178*50424Ssklower checkback(ns)
179*50424Ssklower int ns;
180*50424Ssklower {
181*50424Ssklower int n;
182*50424Ssklower register struct savebuf *s = savebuf.s_next, *t;
183*50424Ssklower while (s != &savebuf) {
184*50424Ssklower iov->iov_len = s->s_n;
185*50424Ssklower n = recvmsg(ns, &msg, s->s_flags);
186*50424Ssklower dbprintf("echoed %d\n", n);
187*50424Ssklower if (verify &&
188*50424Ssklower (n != s->s_n || bcmp((char *)(s + 1), iov->iov_base, n)))
189*50424Ssklower dbprintf("mismatched data or length was %d got %d\n",
190*50424Ssklower s->s_n, n);
191*50424Ssklower t = s; s = s->s_next; remque(t); free((char *)t);
192*50424Ssklower }
193*50424Ssklower }
194*50424Ssklower
put_record(s,flags)19545450Ssklower put_record(s, flags)
19645450Ssklower int s, flags;
19745450Ssklower {
19845450Ssklower int fd, buflen;
19945450Ssklower char *buf;
20045450Ssklower int x, saved_x;
20145450Ssklower
20245450Ssklower msg.msg_flags = flags;
20345450Ssklower if (verbose) {
20445450Ssklower unsigned short *zp, *zlim;
20545450Ssklower if (msg.msg_controllen) {
20645450Ssklower zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len);
20745450Ssklower printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
20845450Ssklower printf("CMsg data: ");
20945450Ssklower x = msg.msg_controllen;
21045450Ssklower zlim = zp + ((x + 1) / 2);
21145450Ssklower while (zp < zlim) printf("%x ", *zp++);
21245450Ssklower putchar ('\n');
21345450Ssklower }
21445450Ssklower if (iov->iov_len) {
21545450Ssklower printf("sending: %s %s",
21645450Ssklower (flags & MSG_OOB ? "(OOB Data)" : ""),
21745450Ssklower (flags & MSG_EOR ? "(Record Mark)" : ""));
21845450Ssklower x = localsize;
21945450Ssklower zp = (unsigned short *)data_msg;
22045450Ssklower zlim = zp + ((x + 1) / 2);
22145450Ssklower while (zp < zlim) printf("%x ", *zp++);
22245450Ssklower putchar ('\n');
22345450Ssklower }
22445450Ssklower }
225*50424Ssklower if (echop)
226*50424Ssklower savedata(iov->iov_len, flags);
22745450Ssklower try(sendmsg, (s, &msg, flags), " put_record ");
22845450Ssklower saved_x = x;
229*50424Ssklower if (echop && (iov->iov_base[0] & 0x80))
230*50424Ssklower checkback(s);
23145450Ssklower msg.msg_control = 0;
23245450Ssklower return (saved_x);
23345450Ssklower }
23445450Ssklower int *datasize = &iov->iov_len;
23545450Ssklower char *cp, *cplim;
23645450Ssklower
get_control_data(type,level)23745450Ssklower get_control_data(type, level)
23845450Ssklower {
23945450Ssklower
24045450Ssklower datasize = (int *)&msg.msg_controllen;
24145450Ssklower cp = cm.cm.cmdata;
24245450Ssklower cplim = cp + sizeof(cm.cm.cmdata);
24345450Ssklower cm.cm.cmhdr.cmsg_level = level;
24445450Ssklower cm.cm.cmhdr.cmsg_type = type;
24545450Ssklower msg.msg_control = cm.data;
24645450Ssklower }
24745450Ssklower
24845450Ssklower
24945450Ssklower
get_record(flags)25045450Ssklower get_record(flags)
25145450Ssklower int *flags;
25245450Ssklower {
25345450Ssklower int factor = 1, x = 0;
25445450Ssklower char workbuf[10240];
25548842Ssklower static repeatcount, repeatsize;
25645450Ssklower
25748842Ssklower if (repeatcount > 0) {
25848842Ssklower repeatcount--;
25948842Ssklower return;
26048842Ssklower }
26145450Ssklower *flags = 0;
26245450Ssklower *datasize = 0;
26345450Ssklower datasize = &iov->iov_len;
26445450Ssklower cp = data_msg + 1;
26545572Ssklower cplim = data_msg + sizeof(data_msg);
26645450Ssklower
26745572Ssklower *data_msg = 0;
26845450Ssklower for(;;) {
26945450Ssklower x = scanf("%s", workbuf);
27045450Ssklower if (x == EOF)
27145450Ssklower break;
27245450Ssklower if (strcmp(workbuf, "oob") == 0)
27345450Ssklower *flags |= MSG_OOB;
27445450Ssklower else if (strcmp(workbuf, "qbit") == 0)
27545450Ssklower *data_msg |= 0x80;
27645450Ssklower else if (strcmp(workbuf, "mbit") == 0)
27745450Ssklower *data_msg |= 0x40;
27845450Ssklower else if (strcmp(workbuf, "eom") == 0)
27945450Ssklower *flags |= MSG_EOR;
28045450Ssklower else if (strcmp(workbuf, "factor") == 0) {
28145450Ssklower x = scanf("%d", &factor);
28245450Ssklower if (factor <= 0) factor = 1;
28345450Ssklower if (x == EOF)
28445450Ssklower break;
28548842Ssklower } else if (strcmp(workbuf, "repeat") == 0) {
28648842Ssklower x = scanf("%d", &repeatcount);
28748842Ssklower if (repeatcount <= 0) repeatcount = 1;
28848842Ssklower if (x == EOF)
28948842Ssklower break;
29045450Ssklower } else {
29145450Ssklower int len = strlen(workbuf);
29245572Ssklower localsize = 1;
29345450Ssklower while ((factor-- > 0) &&
29445450Ssklower ((cp + len) < cplim)) {
29545450Ssklower strcpy(cp, workbuf);
29645450Ssklower cp += len;
29745450Ssklower localsize += len;
29845450Ssklower }
29945450Ssklower *datasize = localsize;
30045450Ssklower if (datasize != &iov->iov_len) {
30145450Ssklower *datasize += sizeof(cm.cm.cmhdr);
30248842Ssklower repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
30345450Ssklower }
30445450Ssklower break;
30545450Ssklower }
30645450Ssklower }
30745450Ssklower errno = 0;
30845450Ssklower return (x);
30945450Ssklower }
310