Commit | Line | Data |
---|---|---|
48435ab0 WJ |
1 | /* ubcx25.c - X.25 abstractions for UBC X25 */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/compat/RCS/ubcx25.c,v 7.4 91/02/22 09:16:13 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/compat/RCS/ubcx25.c,v 7.4 91/02/22 09:16:13 mrose Interim $ | |
9 | * | |
10 | * Contributed by Julian Onions, Nottingham University in the UK | |
11 | * | |
12 | * | |
13 | * $Log: ubcx25.c,v $ | |
14 | * Revision 7.4 91/02/22 09:16:13 mrose | |
15 | * Interim 6.8 | |
16 | * | |
17 | * Revision 7.3 91/01/14 13:33:53 mrose | |
18 | * loader | |
19 | * | |
20 | * Revision 7.2 90/07/09 14:32:28 mrose | |
21 | * sync | |
22 | * | |
23 | * Revision 7.1 89/12/07 01:08:02 mrose | |
24 | * queued writes | |
25 | * | |
26 | * Revision 7.0 89/11/23 21:23:47 mrose | |
27 | * Release 6.0 | |
28 | * | |
29 | */ | |
30 | ||
31 | /* | |
32 | * NOTICE | |
33 | * | |
34 | * Acquisition, use, and distribution of this module and related | |
35 | * materials are subject to the restrictions of a license agreement. | |
36 | * Consult the Preface in the User's Manual for the full terms of | |
37 | * this agreement. | |
38 | * | |
39 | */ | |
40 | ||
41 | ||
42 | /* LINTLIBRARY */ | |
43 | ||
44 | #include <errno.h> | |
45 | #include <stdio.h> | |
46 | #include "general.h" | |
47 | #include "manifest.h" | |
48 | #include "tailor.h" | |
49 | #include "tpkt.h" | |
50 | ||
51 | /* \f 4.[23] UNIX: UBC X25 */ | |
52 | ||
53 | #ifdef X25 | |
54 | #ifdef UBC_X25 | |
55 | ||
56 | #include "x25.h" | |
57 | #include <sys/uio.h> | |
58 | ||
59 | #define X25_MBIT 0x40 | |
60 | #define X25_QBIT 0x80 | |
61 | ||
62 | /* \f */ | |
63 | ||
64 | int start_x25_client (local) | |
65 | struct NSAPaddr *local; | |
66 | { | |
67 | int sd, pgrp; | |
68 | ||
69 | if (local != NULLNA) | |
70 | local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default; | |
71 | if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) { | |
72 | SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket")); | |
73 | return NOTOK; /* Error can be found in errno */ | |
74 | } | |
75 | ||
76 | pgrp = getpid(); | |
77 | if (ioctl(sd, SIOCSPGRP, &pgrp)) { | |
78 | SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP")); | |
79 | return NOTOK; /* Error can be found in errno */ | |
80 | } | |
81 | ||
82 | return sd; | |
83 | } | |
84 | ||
85 | /* \f */ | |
86 | ||
87 | int start_x25_server (local, backlog, opt1, opt2) | |
88 | struct NSAPaddr *local; | |
89 | int backlog, | |
90 | opt1, | |
91 | opt2; | |
92 | { | |
93 | int sd, pgrp; | |
94 | #ifdef notyet | |
95 | #ifdef BSD43 | |
96 | int onoff; | |
97 | #endif | |
98 | #endif | |
99 | CONN_DB zsck; | |
100 | CONN_DB *sck = &zsck; | |
101 | ||
102 | if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) { | |
103 | SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket")); | |
104 | return NOTOK; /* Can't get an X.25 socket */ | |
105 | } | |
106 | ||
107 | pgrp = getpid(); | |
108 | if (ioctl(sd, SIOCSPGRP, &pgrp)) { | |
109 | SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP")); | |
110 | return NOTOK; /* Error can be found in errno */ | |
111 | } | |
112 | ||
113 | if (local != NULLNA) { | |
114 | local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default; | |
115 | if (local -> na_dtelen == 0) { | |
116 | (void) strcpy (local -> na_dte, x25_local_dte); | |
117 | local -> na_dtelen = strlen(x25_local_dte); | |
118 | if (local -> na_pidlen == 0 && *x25_local_pid) | |
119 | local -> na_pidlen = | |
120 | str2sel (x25_local_pid, -1, local -> na_pid, NPSIZE); | |
121 | } | |
122 | } | |
123 | ||
124 | (void) gen2if (local, sck, ADDR_LISTEN); | |
125 | if (bind (sd, sck, sizeof(CONN_DB)) == NOTOK) { | |
126 | SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind")); | |
127 | (void) close_x25_socket (sd); | |
128 | return NOTOK; | |
129 | } | |
130 | ||
131 | ||
132 | #ifdef notyet /* not sure if these are supported... */ | |
133 | #ifndef BSD43 | |
134 | if (opt1) | |
135 | (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0); | |
136 | if (opt2) | |
137 | (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0); | |
138 | #else | |
139 | onoff = 1; | |
140 | if (opt1) | |
141 | (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff); | |
142 | if (opt2) | |
143 | (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff); | |
144 | #endif | |
145 | #endif | |
146 | ||
147 | (void) listen (sd, backlog); | |
148 | ||
149 | return sd; | |
150 | } | |
151 | ||
152 | /* \f */ | |
153 | ||
154 | int join_x25_client (fd, remote) | |
155 | int fd; | |
156 | struct NSAPaddr *remote; | |
157 | { | |
158 | CONN_DB sck; | |
159 | int len = sizeof sck; | |
160 | int nfd; | |
161 | ||
162 | if((nfd = accept (fd, (struct sockaddr *) &sck, &len)) == NOTOK) | |
163 | return NOTOK; | |
164 | (void) if2gen (remote, &sck, ADDR_REMOTE); | |
165 | return nfd; | |
166 | } | |
167 | ||
168 | int join_x25_server (fd, remote) | |
169 | int fd; | |
170 | struct NSAPaddr *remote; | |
171 | { | |
172 | CONN_DB zsck; | |
173 | CONN_DB *sck = &zsck; | |
174 | ||
175 | if (remote == NULLNA || remote -> na_stack != NA_X25) | |
176 | { | |
177 | SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, | |
178 | ("Invalid type na%d", remote->na_stack)); | |
179 | return NOTOK; | |
180 | } | |
181 | (void) gen2if (remote, sck, ADDR_REMOTE); | |
182 | return connect (fd, sck, sizeof (CONN_DB)); | |
183 | } | |
184 | ||
185 | int read_x25_socket (fd, buffer, len) | |
186 | int fd, len; | |
187 | char *buffer; | |
188 | { | |
189 | static u_char mode; | |
190 | static struct iovec iov[2] = { | |
191 | (char *)&mode, 1, | |
192 | "", 0 | |
193 | }; | |
194 | char *p = buffer; | |
195 | int cc, count = 0, total = len; | |
196 | ||
197 | do { | |
198 | iov[1].iov_base = p; | |
199 | iov[1].iov_len = total > X25_PACKETSIZE ? X25_PACKETSIZE : total; | |
200 | ||
201 | switch (cc = readv (fd, iov, 2)) { | |
202 | /* | |
203 | * for the -1,0 & 1 cases these returns should be ok | |
204 | * if it's the first time through, then they are valid anyway | |
205 | * later stages means the M bit is set so there must | |
206 | * be more data else someone is violating the | |
207 | * protocol badly. | |
208 | */ | |
209 | ||
210 | case NOTOK: | |
211 | case 0: | |
212 | return cc; | |
213 | ||
214 | case 1: | |
215 | SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, | |
216 | ("strange return from read_x25_socket")); | |
217 | return NOTOK; | |
218 | ||
219 | default: | |
220 | cc --; /* discount the info byte */ | |
221 | count += cc; | |
222 | p += cc; | |
223 | total -= cc; | |
224 | } | |
225 | } while (len > 0 && (mode & X25_MBIT)); | |
226 | DLOG (compat_log, LLOG_DEBUG, ("X25 read, total %d/%d", count, len)); | |
227 | ||
228 | return count; | |
229 | } | |
230 | ||
231 | #ifdef UBC_X25_WRITEV | |
232 | /* God this all very bizarre - iovecs work on read but not write!! */ | |
233 | ||
234 | /* | |
235 | * OK, this is due to a bug in UBC implementation. It may or may not | |
236 | * be fixed in later versions. If writev allows you to write single | |
237 | * bytes in the first vector then use this version. It's much more | |
238 | * efficient. | |
239 | */ | |
240 | ||
241 | int write_x25_socket (fd, buffer, len) | |
242 | int fd, len; | |
243 | char *buffer; | |
244 | { | |
245 | static u_char mode; | |
246 | static struct iovec iov[2] = { | |
247 | (char *)&mode, 1, | |
248 | "", 0 | |
249 | }; | |
250 | int cc; | |
251 | char *p = buffer; | |
252 | int count, total = 0; | |
253 | ||
254 | do { | |
255 | count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len; | |
256 | mode = len > X25_PACKETSIZE ? X25_MBIT : 0; | |
257 | iov[1].iov_base = p; | |
258 | iov[1].iov_len = count; | |
259 | switch (cc = writev (fd, iov, 2)) | |
260 | { | |
261 | case NOTOK: | |
262 | case 0: | |
263 | return cc; | |
264 | ||
265 | case 1: | |
266 | SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, | |
267 | ("strange return from write_x25_socket")); | |
268 | return NOTOK; | |
269 | ||
270 | default: | |
271 | cc --; | |
272 | len -= cc; | |
273 | p += cc; | |
274 | total += cc; | |
275 | } | |
276 | } while (len > 0); | |
277 | DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len)); | |
278 | return total; | |
279 | } | |
280 | #else | |
281 | int write_x25_socket (fd, buffer, len) | |
282 | int fd, len; | |
283 | char *buffer; | |
284 | { | |
285 | char mybuffer[X25_PACKETSIZE+1]; | |
286 | char *p = buffer; | |
287 | int count, total = 0; | |
288 | int cc; | |
289 | ||
290 | do { | |
291 | count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len; | |
292 | mybuffer[0] = len > X25_PACKETSIZE ? X25_MBIT : 0; | |
293 | bcopy (p, &mybuffer[1], count); | |
294 | switch (cc = write (fd, mybuffer, count + 1)) | |
295 | { | |
296 | case NOTOK: | |
297 | case 0: | |
298 | return cc; | |
299 | ||
300 | case 1: | |
301 | SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, | |
302 | ("strange return from write_x25_socket")); | |
303 | return NOTOK; | |
304 | ||
305 | default: | |
306 | cc --; | |
307 | len -= cc; | |
308 | p += cc; | |
309 | total += cc; | |
310 | } | |
311 | } while (len > 0); | |
312 | DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len)); | |
313 | return total; | |
314 | } | |
315 | #endif | |
316 | ||
317 | #else /* UBC_X25 */ | |
318 | int _ubcx25_stub2 () {}; | |
319 | #endif /* UBC_X25 */ | |
320 | #else /* X25 */ | |
321 | int _ubcx25_stub () {}; | |
322 | #endif /* X25 */ |