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
main(argc,argv)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
xisrc()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
savedata(n,flags)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
checkback(ns)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
put_record(s,flags)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
get_control_data(type,level)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
get_record(flags)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