Commit | Line | Data |
---|---|---|
b160707d KS |
1 | /* |
2 | * Copyright (c) 1988, 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.1 (Berkeley) %G%"; | |
9 | #endif /* not lint */ | |
10 | ||
11 | /* | |
12 | * This is a test program to be a source for TP4 connections. | |
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 sockaddr_iso to_s = { sizeof(to_s), AF_ISO }, *to = &to_s; | |
36 | fd_set readfds, writefds, exceptfds; | |
37 | long size, count = 10; | |
38 | int verbose = 1, selectp, type = SOCK_SEQPACKET, nobuffs, errno, playtag = 0; | |
39 | int verify = 0; | |
40 | short portnumber = 3000; | |
41 | char your_it[] = "You're it!"; | |
42 | char *port, *conndata, data_msg[2048]; | |
43 | struct iovec iov[1] = {data_msg}; | |
44 | union { | |
45 | struct { | |
46 | struct cmsghdr cmhdr; | |
47 | char cmdata[128 - sizeof (struct cmsghdr)]; | |
48 | } cm; | |
49 | char data[128]; | |
50 | } cm; | |
51 | struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0}; | |
52 | ||
53 | main(argc, argv) | |
54 | int argc; | |
55 | char *argv[]; | |
56 | { | |
57 | register char **av = argv; | |
58 | register char *cp; | |
59 | struct iso_addr iso_addr(); | |
60 | u_long len; | |
61 | int handy; | |
62 | ||
63 | while(--argc > 0) { | |
64 | av++; | |
65 | if(strcmp(*av,"Servername")==0) { | |
66 | av++; | |
67 | port = *av; | |
68 | argc--; | |
69 | } else if(strcmp(*av,"conndata")==0) { | |
70 | av++; | |
71 | conndata = *av; | |
72 | argc--; | |
73 | } else if(strcmp(*av,"host")==0) { | |
74 | av++; | |
75 | to_s.siso_addr = iso_addr(*av); | |
76 | argc--; | |
77 | } else if(strcmp(*av,"port")==0) { | |
78 | av++; | |
79 | sscanf(*av,"%hd",&portnumber); | |
80 | argc--; | |
81 | } else if(strcmp(*av,"count")==0) { | |
82 | av++; | |
83 | sscanf(*av,"%ld",&count); | |
84 | argc--; | |
85 | } else if(strcmp(*av,"size")==0) { | |
86 | av++; | |
87 | sscanf(*av,"%ld",&size); | |
88 | iov->iov_len = size; | |
89 | } else if(strcmp(*av,"stream")==0) { | |
90 | type = SOCK_STREAM; | |
91 | } else if (strcmp(*av,"eon") == 0) { | |
92 | unsigned long l, inet_addr(); | |
93 | ||
94 | l = inet_addr(*++av); argc--; | |
95 | to_s.siso_addr = eon; | |
96 | bcopy((char *)&l, &to_s.siso_data[15], 4); | |
97 | } | |
98 | } | |
99 | if (port) { | |
100 | to_s.siso_tlen = strlen(port); | |
101 | len = 1 + to_s.siso_nlen + strlen(port) | |
102 | + sizeof(*to) - sizeof(struct iso_addr); | |
103 | if (len > sizeof(*to)) { | |
104 | to = (struct sockaddr_iso *)malloc(len); | |
105 | bzero(to, len); | |
106 | *to = to_s; | |
107 | to->siso_len = len; | |
108 | } | |
109 | bcopy(port, TSEL(to), strlen(port)); | |
110 | } else { | |
111 | to_s.siso_tlen = sizeof(portnumber); | |
112 | portnumber = htons(portnumber); | |
113 | bcopy((char *)&portnumber, TSEL(to), sizeof(portnumber)); | |
114 | } | |
115 | ||
116 | tisrc(); | |
117 | } | |
118 | ||
119 | tisrc() { | |
120 | int x, s, pid, on = 1, flags = 8, n; | |
121 | ||
122 | try(socket, (AF_ISO, type, 0),""); | |
123 | s = x; | |
124 | ||
125 | /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), "");*/ | |
126 | ||
127 | if (conndata) doconndata(s); | |
128 | ||
129 | try(connect, (s, (struct sockaddr *) to, to->siso_len), ""); | |
130 | ||
131 | if (selectp) { | |
132 | FD_ZERO(&writefds); FD_SET(s, &writefds); | |
133 | select(1, &writefds, 0, 0, 0); | |
134 | } | |
135 | while (count-- > 0) { | |
136 | if (size <= 0 && get_record(&flags) == EOF) | |
137 | exit(0); | |
138 | n = put_record(s, flags); | |
139 | if (n < iov->iov_len) { | |
140 | if (n==-1 && errno == 55) { | |
141 | nobuffs++; | |
142 | count++; | |
143 | continue; | |
144 | } | |
145 | fprintf(stderr, "wrote %d < %d, count %d,", | |
146 | n, iov->iov_len, count); | |
147 | perror("due to"); | |
148 | } | |
149 | } | |
150 | if (playtag) { | |
151 | printf("Tag time!\n"); | |
152 | iov->iov_base = your_it; | |
153 | iov->iov_len = sizeof your_it; | |
154 | sendmsg(s, &msg, MSG_EOR); | |
155 | sendmsg(s, &msg, MSG_EOR); | |
156 | iov->iov_base = data_msg; | |
157 | iov->iov_len = sizeof data_msg; | |
158 | try(recvmsg, (s, &msg, flags), " playtag "); | |
159 | } | |
160 | if(nobuffs) { | |
161 | printf("looped %d times waiting for bufs\n", nobuffs); | |
162 | } | |
163 | } | |
164 | int localsize; | |
165 | char dupbuf[4096]; | |
166 | ||
167 | put_record(s, flags) | |
168 | int s, flags; | |
169 | { | |
170 | int fd, buflen; | |
171 | char *buf; | |
172 | struct sockaddr *to; | |
173 | int x, saved_x; | |
174 | ||
175 | msg.msg_flags = flags; | |
176 | if (verbose) { | |
177 | unsigned short *zp, *zlim; | |
178 | if (msg.msg_controllen) { | |
179 | zp = (unsigned short *)&(cm.cm.cmhdr.cmsg_len); | |
180 | printf("(CMessage Type is %x) ", cm.cm.cmhdr.cmsg_type); | |
181 | printf("CMsg data: "); | |
182 | x = msg.msg_controllen; | |
183 | zlim = zp + ((x + 1) / 2); | |
184 | while (zp < zlim) printf("%x ", *zp++); | |
185 | putchar ('\n'); | |
186 | } | |
187 | if (iov->iov_len) { | |
188 | printf("sending: %s %s", | |
189 | (flags & MSG_OOB ? "(OOB Data)" : ""), | |
190 | (flags & MSG_EOR ? "(Record Mark)" : "")); | |
191 | x = localsize; | |
192 | zp = (unsigned short *)data_msg; | |
193 | zlim = zp + ((x + 1) / 2); | |
194 | while (zp < zlim) printf("%x ", *zp++); | |
195 | putchar ('\n'); | |
196 | } | |
197 | } | |
198 | if (verify) { | |
199 | buflen = iov->iov_len; | |
200 | bcopy(iov->iov_base, dupbuf, buflen); | |
201 | } | |
202 | try(sendmsg, (s, &msg, flags), " put_record "); | |
203 | saved_x = x; | |
204 | while (verify && buflen > 0) { | |
205 | iov->iov_len = buflen; | |
206 | iov->iov_base = dupbuf; | |
207 | try(recvmsg, (s, &msg, flags), " put_record "); | |
208 | printf("verify got %d\n", x); | |
209 | buflen -= x; | |
210 | } | |
211 | msg.msg_control = 0; | |
212 | return (saved_x); | |
213 | } | |
214 | int *datasize = &iov->iov_len; | |
215 | char *cp, *cplim; | |
216 | ||
217 | get_control_data(type) | |
218 | { | |
219 | ||
220 | datasize = (int *)&msg.msg_controllen; | |
221 | cp = cm.cm.cmdata; | |
222 | cplim = cp + sizeof(cm.cm.cmdata); | |
223 | cm.cm.cmhdr.cmsg_level = SOL_TRANSPORT; | |
224 | cm.cm.cmhdr.cmsg_type = type; | |
225 | msg.msg_control = cm.data; | |
226 | } | |
227 | ||
228 | doconndata(s) | |
229 | { | |
230 | get_control_data(TPOPT_CONN_DATA); | |
231 | *datasize = strlen(conndata) + sizeof(cm.cm.cmhdr); | |
232 | cm.cm.cmhdr.cmsg_len = *datasize; | |
233 | bcopy(conndata, cp, *datasize); | |
234 | put_record(s, 0); | |
235 | } | |
236 | ||
237 | ||
238 | ||
239 | get_record(flags) | |
240 | int *flags; | |
241 | { | |
242 | int factor = 1, x = 0; | |
243 | char workbuf[10240]; | |
244 | ||
245 | *flags = 0; | |
246 | *datasize = 0; | |
247 | datasize = &iov->iov_len; | |
248 | cp = data_msg; | |
249 | cplim = cp + sizeof(data_msg); | |
250 | ||
251 | for(;;) { | |
252 | x = scanf("%s", workbuf); | |
253 | if (x == EOF) | |
254 | break; | |
255 | if (strcmp(workbuf, "disc") == 0) | |
256 | x = get_control_data(TPOPT_DISC_DATA); | |
257 | else if (strcmp(workbuf, "cfrm") == 0) | |
258 | x = get_control_data(TPOPT_CFRM_DATA); | |
259 | else if (strcmp(workbuf, "oob") == 0) | |
260 | *flags |= MSG_OOB; | |
261 | else if (strcmp(workbuf, "eom") == 0) | |
262 | *flags |= MSG_EOR; | |
263 | else if (strcmp(workbuf, "factor") == 0) { | |
264 | x = scanf("%d", &factor); | |
265 | if (factor <= 0) factor = 1; | |
266 | if (x == EOF) | |
267 | break; | |
268 | } else { | |
269 | int len = strlen(workbuf); | |
270 | localsize = 0; | |
271 | while ((factor-- > 0) && | |
272 | ((cp + len) < cplim)) { | |
273 | strcpy(cp, workbuf); | |
274 | cp += len; | |
275 | localsize += len; | |
276 | } | |
277 | *datasize = localsize; | |
278 | if (datasize != &iov->iov_len) { | |
279 | *datasize += sizeof(cm.cm.cmhdr); | |
280 | cm.cm.cmhdr.cmsg_len = *datasize; | |
281 | } | |
282 | break; | |
283 | } | |
284 | } | |
285 | errno = 0; | |
286 | return (x); | |
287 | } |