386BSD 0.1 development
[unix-history] / usr / othersrc / contrib / isode / compat / bridge.c
CommitLineData
48435ab0
WJ
1/* bridge.c - X.25 abstractions for TCP bridge to X25 */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/compat/RCS/bridge.c,v 7.2 91/02/22 09:14:58 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/compat/RCS/bridge.c,v 7.2 91/02/22 09:14:58 mrose Interim $
9 *
10 * Contributed by Julian Onions, Nottingham University in the UK
11 *
12 *
13 * $Log: bridge.c,v $
14 * Revision 7.2 91/02/22 09:14:58 mrose
15 * Interim 6.8
16 *
17 * Revision 7.1 90/07/09 14:31:32 mrose
18 * sync
19 *
20 * Revision 7.0 89/11/23 21:22:55 mrose
21 * Release 6.0
22 *
23 */
24
25/*
26 * NOTICE
27 *
28 * Acquisition, use, and distribution of this module and related
29 * materials are subject to the restrictions of a license agreement.
30 * Consult the Preface in the User's Manual for the full terms of
31 * this agreement.
32 *
33 */
34
35
36/* LINTLIBRARY */
37
38#include <errno.h>
39#include <stdio.h>
40#include "general.h"
41#include "manifest.h"
42#include "tailor.h"
43#include "internet.h"
44#include "tpkt.h"
45
46/* \f TCP/X.25 BRIDGE */
47
48#ifdef BRIDGE_X25
49
50
51static int assfd[FD_SETSIZE];
52static char bridge_inited = 0;
53
54/* \f */
55
56/* ARGSUSED */
57
58int start_bridge_client (local)
59struct NSAPaddr *local;
60{
61 int sd;
62 u_short port;
63 register struct servent *sp;
64
65 if ((sp = getservbyname ("x25bridge", "tcp")) == NULL)
66 port = x25_bridge_port;
67 else
68 port = sp -> s_port;
69
70 if ((sd = in_connect (x25_bridge_host, port)) == NOTOK)
71 return NOTOK;
72
73 if (write_tcp_socket (sd, "\01", 1) != 1) {
74 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("initial write"));
75
76 (void) close_tcp_socket (sd);
77 return NOTOK;
78 }
79
80 return sd;
81}
82
83/* \f */
84
85static int in_connect (addr, port)
86char *addr;
87u_short port;
88{
89 int sd;
90 struct sockaddr_in in_socket;
91 register struct sockaddr_in *isock = &in_socket;
92 register struct hostent *hp;
93
94 if ((hp = gethostbystring (addr)) == NULL) {
95 SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", addr));
96
97 return NOTOK;
98 }
99
100 bzero ((char *) isock, sizeof *isock);
101 isock -> sin_family = hp -> h_addrtype;
102 isock -> sin_port = port;
103 inaddr_copy (hp, isock);
104
105 if ((sd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK) {
106 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("start_tcp_client"));
107
108 return NOTOK;
109 }
110
111 if (join_tcp_server (sd, isock) == NOTOK) {
112 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("join_tcp_server"));
113
114 (void) close_tcp_socket (sd);
115 return NOTOK;
116 }
117
118 return sd;
119}
120
121/* \f */
122
123int join_bridge_server (fd, remote)
124int fd;
125register struct NSAPaddr *remote;
126{
127 if (remote != NULLNA)
128 remote -> na_stack = NA_BRG, remote -> na_community = ts_comm_x25_default;
129 if (bridge_write_nsap_addr (fd, remote, write_tcp_socket) == NOTOK) {
130 SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("write of NSAP failed"));
131
132 return NOTOK;
133 }
134
135 return fd;
136}
137
138/* \f */
139
140int start_bridge_server (local, backlog, opt1, opt2)
141struct NSAPaddr *local;
142int backlog,
143 opt1,
144 opt2;
145{
146 int len,
147 new,
148 sd;
149 u_short port;
150 struct servent *sp;
151 struct sockaddr_in in_socket;
152 register struct sockaddr_in *isock = &in_socket;
153
154 if (bridge_inited == 0) {
155 for (sd = 0; sd < FD_SETSIZE; sd++)
156 assfd[sd] = NOTOK;
157 bridge_inited = 1;
158 }
159 if ((sp = getservbyname ("x25bridge", "tcp")) == NULL)
160 port = x25_bridge_port;
161 else
162 port = sp -> s_port;
163
164 if ((sd = in_connect (x25_bridge_host, port)) == NOTOK)
165 return NOTOK;
166
167 if (write_tcp_socket (sd, "\02", 1) != 1) {
168 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("initial write"));
169
170 (void) close_tcp_socket (sd);
171 return NOTOK;
172 }
173
174 if (local != NULLNA)
175 local -> na_stack = NA_BRG, local -> na_community = ts_comm_x25_default;
176 if (local != NULLNA && local -> na_dtelen == 0)
177 {
178 (void) strcpy (local -> na_dte, x25_bridge_addr);
179 local -> na_dtelen = strlen(x25_bridge_addr);
180 }
181 if (local != NULLNA) {
182 DLOG (compat_log, LLOG_DEBUG,
183 ("addr", "type=%d '%s' len=%d",
184 local -> na_stack, local -> na_dte,local -> na_dtelen));
185 DLOG (compat_log, LLOG_DEBUG,
186 ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
187 local -> na_pid, local -> na_pidlen,
188 local -> na_fac, local -> na_faclen,
189 local -> na_pid, local -> na_pidlen,
190 local -> na_cudf, local -> na_cudflen));
191 }
192
193 if (bridge_write_nsap_addr (sd, local, write_tcp_socket) == NOTOK) {
194 SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("write of NSAP failed"));
195
196 (void) close_tcp_socket (sd);
197 return NOTOK;
198 }
199
200 if ((new = in_listen (backlog, opt1, opt2)) == NOTOK) {
201 (void) close_tcp_socket (sd);
202 return NOTOK;
203 }
204
205 len = sizeof *isock;
206 if (getsockname (new, (struct sockaddr *) isock, &len) == NOTOK) {
207 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("getsockname"));
208
209out: ;
210 (void) close_tcp_socket (sd);
211 (void) close_tcp_socket (new);
212 return NOTOK;
213 }
214
215 isock -> sin_family = htons (isock -> sin_family);
216 if (write_tcp_socket (sd, (char *)isock, sizeof *isock) != sizeof *isock) {
217 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("write of sockaddr_in"));
218
219 goto out;
220 }
221 assfd[new] = sd;
222
223 return new;
224}
225
226int get_bridge_assfd(fd)
227int fd;
228{
229 if (!bridge_inited)
230 return NOTOK;
231 return assfd[fd];
232}
233
234/* \f */
235
236static int in_listen (backlog, opt1, opt2)
237int backlog,
238 opt1,
239 opt2;
240{
241 int sd;
242 char *cp;
243 struct sockaddr_in lo_socket;
244 register struct sockaddr_in *lsock = &lo_socket;
245 register struct hostent *hp;
246
247 if ((hp = gethostbystring (cp = getlocalhost ())) == NULL) {
248 SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", cp));
249
250 return NOTOK;
251 }
252
253 bzero ((char *) lsock, sizeof *lsock);
254 lsock -> sin_family = hp -> h_addrtype;
255 inaddr_copy (hp, lsock);
256
257 if ((sd = start_tcp_server (lsock, backlog, opt1, opt2)) == NOTOK) {
258 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("start_tcp_server"));
259
260 return NOTOK;
261 }
262
263 return sd;
264}
265
266/* \f */
267
268int join_bridge_client (fd, remote)
269int fd;
270struct NSAPaddr *remote;
271{
272 int new;
273 struct sockaddr_in in_socket;
274 struct NSAPaddr sock;
275
276 if ((new = join_tcp_client (fd, &in_socket)) == NOTOK) {
277 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("join_tcp_client"));
278
279 return NOTOK;
280 }
281
282 if (bridge_read_nsap_addr (new, &sock, read_tcp_socket) == NOTOK) {
283 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("read of NSAP"));
284
285 (void) close_tcp_socket (new);
286 return NOTOK;
287 }
288 DLOG (compat_log, LLOG_DEBUG,
289 ("addr", "type=%d '%s' len=%d", sock.na_stack, sock.na_dte,
290 sock.na_dtelen));
291 DLOG (compat_log, LLOG_DEBUG,
292 ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
293 sock.na_pid, sock.na_pidlen,
294 sock.na_fac, sock.na_faclen,
295 sock.na_pid, sock.na_pidlen,
296 sock.na_cudf, sock.na_cudflen));
297 sock.na_stack = ntohl (sock.na_stack);
298 *remote = sock;
299 DLOG (compat_log, LLOG_DEBUG,
300 ("addr", "type=%d '%s' len=%d",
301 remote -> na_stack, remote -> na_dte,remote -> na_dtelen));
302 DLOG (compat_log, LLOG_DEBUG,
303 ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
304 remote -> na_pid, remote -> na_pidlen,
305 remote -> na_fac, remote -> na_faclen,
306 remote -> na_pid, remote -> na_pidlen,
307 remote -> na_cudf, remote -> na_cudflen));
308 return new;
309}
310
311int close_bridge_socket (sd)
312int sd;
313{
314 if (bridge_inited && assfd[sd] != NOTOK)
315 (void) close_tcp_socket (assfd[sd]);
316 assfd[sd] = NOTOK;
317 return close_tcp_socket (sd);
318}
319
320/* ARGSUSED */
321
322int bridgediscrim (na)
323struct NSAPaddr *na;
324{
325#ifndef X25
326 return 1; /* must be bridge */
327#else
328 int len = strlen (x25_bridge_discrim);
329
330 if (len == 1 && *x25_bridge_discrim == '-')
331 return 0;
332
333 return (len == 0 ? 1
334 : strncmp (na -> na_dte, x25_bridge_discrim, len) == 0);
335#endif
336}
337#endif
338
339/*
340 * Structure is as follows :-
341 * 0-1 type
342 * 2-17 dte
343 * 18 dte len
344 * 19-22 pid
345 * 23 pid len
346 * 24-39 user data
347 * 40 user data len
348 * 41-46 facilities
349 * 47 facility length
350 */
351
352int bridge_write_nsap_addr (fd, nsap, writefnx)
353int fd;
354struct NSAPaddr *nsap;
355IFP writefnx;
356{
357 u_short na_stack;
358 char buffer[50];
359
360 if (nsap == NULLNA || (na_stack = nsap -> na_stack) != NA_BRG)
361 return NOTOK;
362 na_stack = htons(na_stack);
363 bcopy ((char *)&na_stack, buffer, sizeof(na_stack));
364 bcopy (nsap -> na_dte, &buffer[2], 16);
365 buffer[18] = nsap -> na_dtelen;
366 bcopy (nsap -> na_pid, &buffer[19], 4);
367 buffer[23] = nsap -> na_pidlen;
368 bcopy (nsap -> na_cudf, &buffer[24], 16);
369 buffer[40] = nsap -> na_cudflen;
370 bcopy (nsap -> na_fac, &buffer[41], 6);
371 buffer[47] = nsap -> na_faclen;
372 if ((*writefnx) (fd, buffer, 48) != 48)
373 return NOTOK;
374 return OK;
375}
376
377int bridge_read_nsap_addr (fd, nsap, readfnx)
378int fd;
379struct NSAPaddr *nsap;
380IFP readfnx;
381{
382 u_short na_stack;
383 char buffer[50];
384
385 if (readx (fd, buffer, 48, readfnx) != 48)
386 return NOTOK;
387 bcopy (buffer, (char *)&na_stack, sizeof(na_stack));
388 na_stack = ntohs(na_stack);
389 if (na_stack != NA_BRG)
390 return NOTOK;
391 nsap -> na_stack = na_stack;
392 bcopy (&buffer[2], nsap -> na_dte, 16);
393 nsap -> na_dtelen = buffer[18];
394 bcopy (&buffer[19], nsap -> na_pid, 4);
395 nsap -> na_pidlen = buffer[23];
396 bcopy (&buffer[24], nsap -> na_cudf, 16);
397 nsap -> na_cudflen = buffer[40];
398 bcopy (&buffer[41], nsap -> na_fac, 6);
399 nsap -> na_faclen = buffer[47];
400 return OK;
401}
402
403static int readx (fd, buffer, n, readfnx)
404int fd;
405char *buffer;
406int n;
407IFP readfnx;
408{
409 register int i,
410 cc;
411 register char *bp;
412
413 for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) {
414 switch (cc = (*readfnx) (fd, bp, i)) {
415 case NOTOK:
416 return (i = bp - buffer) ? i : NOTOK;
417
418 case OK:
419 break;
420
421 default:
422 continue;
423 }
424 break;
425 }
426
427 return (bp - buffer);
428}