xref: /original-bsd/sys/tests/netccitt/xi_src.c (revision f955cb91)
1 /*-
2  * Copyright (c) 1988, 1991 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, 1991 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[] = "@(#)xi_src.c	7.6 (Berkeley) 07/15/91";
16 #endif /* not lint */
17 
18 /*
19  * This is a test program to be a source for X.25 connections.
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 #include <netccitt/x25.h>
28 
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include <netdb.h>
33 
34 
35 #define dbprintf if(verbose)printf
36 #ifdef __STDC__
37 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,#a,x);\
38 		if(x<0) {perror(#a); exit(1);}}
39 #else
40 #define try(a,b,c) {x = (a b); dbprintf("%s%s returns %d\n",c,"a",x);\
41 		if(x<0) {perror("a"); exit(1);}}
42 #endif
43 
44 fd_set	readfds, writefds, exceptfds;
45 long size, count = 10;
46 int verbose = 1, selectp, type = SOCK_STREAM, nobuffs, errno, playtag = 0;
47 int verify = 0, mqdata, protolisten = 0, echop = 0;
48 unsigned char protodata[2] = {0, 1};
49 short portnumber = 3000;
50 struct sockaddr_x25 to;
51 char your_it[] = "You're it!";
52 char *port, *conndata, data_msg[2048];
53 struct iovec iov[1] = {data_msg};
54 union {
55     struct {
56 	    struct cmsghdr	cmhdr;
57 	    char		cmdata[128 - sizeof (struct cmsghdr)];
58     } cm;
59     char data[128];
60 } cm;
61 struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0};
62 
63 main(argc, argv)
64 int argc;
65 char *argv[];
66 {
67 	register char **av = argv;
68 	register char *cp;
69 	u_long len;
70 	int handy;
71 
72 	while(--argc > 0) {
73 		av++;
74 		if (strcmp(*av,"dest")==0) {
75 			av++;
76 			ccitt_addr(*av, &to);
77 			argc--;
78 		} else if (strcmp(*av,"count")==0) {
79 			av++;
80 			sscanf(*av,"%ld",&count);
81 			argc--;
82 		} else if (strcmp(*av,"size")==0) {
83 			av++;
84 			sscanf(*av,"%ld",&size);
85 			argc--;
86 		} else if (strcmp(*av,"protolisten")==0) {
87 			av++;
88 			protolisten = 1;
89 			sscanf(*av,"%ld",&handy);
90 			argc--;
91 			protodata[0] = handy;
92 		} else if (strcmp(*av,"protonolisten")==0) {
93 			av++;
94 			protolisten = 1;
95 			sscanf(*av,"%ld",&handy);
96 			argc--;
97 			protodata[0] = handy;
98 			protodata[1] = 0;
99 		}
100 	}
101 	xisrc();
102 }
103 
104 xisrc() {
105 	int x, s, pid, on = 1, flags = 8, n;
106 
107 	try(socket, (AF_CCITT, type, 0),"");
108 	s = x;
109 
110 	/*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/
111 
112 	if (protolisten) {
113 		try(setsockopt, (s, CCITTPROTO_X25, PK_PRLISTEN,
114 					protodata, sizeof (protodata)), "");
115 	    exit(0);
116 	}
117 
118 	to.x25_opts.op_flags |= X25_MQBIT;
119 	try(connect, (s, (struct sockaddr *) &to, to.x25_len), "");
120 
121 	if (selectp) {
122 		FD_ZERO(&writefds); FD_SET(s, &writefds);
123 		select(1, &writefds, 0, 0, 0);
124 	}
125 	while (count-- > 0) {
126 		if (size <= 0 && get_record(&flags) == EOF)
127 			exit(0);
128 		n = put_record(s, flags);
129 		if (n < iov->iov_len) {
130 			if (n==-1 && errno == 55) {
131 				nobuffs++;
132 				count++;
133 				continue;
134 			}
135 			fprintf(stderr, "wrote %d < %d, count %d,",
136 						n, iov->iov_len, count);
137 			perror("due to");
138 		}
139 	}
140 	if (playtag) {
141 		printf("Tag time!\n");
142 		iov->iov_base = your_it;
143 		iov->iov_len = sizeof your_it;
144 		sendmsg(s, &msg, MSG_EOR);
145 		sendmsg(s, &msg, MSG_EOR);
146 		iov->iov_base = data_msg;
147 		iov->iov_len = sizeof data_msg;
148 		try(recvmsg, (s, &msg, flags), " playtag ");
149 	}
150 	if (nobuffs) {
151 		printf("looped %d times waiting for bufs\n", nobuffs);
152 	}
153 }
154 int localsize;
155 char dupbuf[4096];
156 
157 struct savebuf {
158 	struct savebuf *s_next;
159 	struct savebuf *s_prev;
160 	int	s_n;
161 	int	s_flags;
162 } savebuf = {&savebuf, &savebuf};
163 
164 void
165 savedata(n, flags)
166 int n;
167 {
168 	register struct savebuf *s = (struct savebuf *)malloc(n + sizeof *s);
169 	if (s == 0)
170 		return;
171 	insque(s, savebuf.s_prev);
172 	s->s_n = n;
173 	s->s_flags = flags;
174 	if (verify)
175 		bcopy(iov->iov_base, (char *)(s + 1), n);
176 }
177 
178 checkback(ns)
179 int ns;
180 {
181 	int n;
182 	register struct savebuf *s = savebuf.s_next, *t;
183 	while (s != &savebuf) {
184 		iov->iov_len = s->s_n;
185 		n = recvmsg(ns, &msg, s->s_flags);
186 		dbprintf("echoed %d\n", n);
187 		if (verify &&
188 		    (n != s->s_n || bcmp((char *)(s + 1), iov->iov_base, n)))
189 			dbprintf("mismatched data or length was %d got %d\n",
190 				s->s_n, n);
191 		t = s; s = s->s_next; remque(t); free((char *)t);
192 	}
193 }
194 
195 put_record(s, flags)
196 int s, flags;
197 {
198 	int fd, buflen;
199 	char *buf;
200 	int x, saved_x;
201 
202 	msg.msg_flags = flags;
203 	if (verbose) {
204 		unsigned short *zp, *zlim;
205 		if (msg.msg_controllen) {
206 			zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len);
207 			printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type);
208 			printf("CMsg data: ");
209 			x = msg.msg_controllen;
210 			zlim = zp + ((x + 1) / 2);
211 			while (zp < zlim) printf("%x ", *zp++);
212 			putchar ('\n');
213 		}
214 		if (iov->iov_len) {
215 			printf("sending: %s %s",
216 			(flags & MSG_OOB ? "(OOB Data)" : ""),
217 				(flags & MSG_EOR ? "(Record Mark)" : ""));
218 			x = localsize;
219 			zp = (unsigned short *)data_msg;
220 			zlim = zp + ((x + 1) / 2);
221 			while (zp < zlim) printf("%x ", *zp++);
222 			putchar ('\n');
223 		}
224 	}
225 	if (echop)
226 		savedata(iov->iov_len, flags);
227 	try(sendmsg, (s, &msg, flags), " put_record ");
228 	saved_x = x;
229 	if (echop && (iov->iov_base[0] & 0x80))
230 		checkback(s);
231 	msg.msg_control = 0;
232 	return (saved_x);
233 }
234 int *datasize = &iov->iov_len;
235 char *cp, *cplim;
236 
237 get_control_data(type, level)
238 {
239 
240 	datasize = (int *)&msg.msg_controllen;
241 	cp = cm.cm.cmdata;
242 	cplim = cp + sizeof(cm.cm.cmdata);
243 	cm.cm.cmhdr.cmsg_level = level;
244 	cm.cm.cmhdr.cmsg_type = type;
245 	msg.msg_control = cm.data;
246 }
247 
248 
249 
250 get_record(flags)
251 int *flags;
252 {
253 	int factor = 1, x = 0;
254 	char workbuf[10240];
255 	static repeatcount, repeatsize;
256 
257 	if (repeatcount > 0) {
258 		repeatcount--;
259 		return;
260 	}
261 	*flags = 0;
262 	*datasize = 0;
263 	datasize = &iov->iov_len;
264 	cp = data_msg + 1;
265 	cplim  = data_msg + sizeof(data_msg);
266 
267 	*data_msg = 0;
268 	for(;;) {
269 		x = scanf("%s", workbuf);
270 		if (x == EOF)
271 			break;
272 		if (strcmp(workbuf, "oob") == 0)
273 			*flags |= MSG_OOB;
274 		else if (strcmp(workbuf, "qbit") == 0)
275 			*data_msg |= 0x80;
276 		else if (strcmp(workbuf, "mbit") == 0)
277 			*data_msg |= 0x40;
278 		else if (strcmp(workbuf, "eom") == 0)
279 			*flags |= MSG_EOR;
280 		else if (strcmp(workbuf, "factor") == 0) {
281 			x = scanf("%d", &factor);
282 			if (factor <= 0) factor = 1;
283 			if (x == EOF)
284 				break;
285 		} else if (strcmp(workbuf, "repeat") == 0) {
286 			x = scanf("%d", &repeatcount);
287 			if (repeatcount <= 0) repeatcount = 1;
288 			if (x == EOF)
289 				break;
290 		} else {
291 			int len = strlen(workbuf);
292 			localsize = 1;
293 			while ((factor-- > 0) &&
294 			       ((cp + len) < cplim)) {
295 					strcpy(cp, workbuf);
296 					cp += len;
297 					localsize += len;
298 			}
299 			*datasize = localsize;
300 			if (datasize != &iov->iov_len) {
301 				*datasize += sizeof(cm.cm.cmhdr);
302 				repeatsize = cm.cm.cmhdr.cmsg_len = *datasize;
303 			}
304 			break;
305 		}
306 	}
307 	errno = 0;
308 	return (x);
309 }
310