summaryrefslogtreecommitdiffstats
path: root/src/isode/compat/bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/isode/compat/bridge.c')
-rw-r--r--src/isode/compat/bridge.c434
1 files changed, 434 insertions, 0 deletions
diff --git a/src/isode/compat/bridge.c b/src/isode/compat/bridge.c
new file mode 100644
index 000000000..45fd18179
--- /dev/null
+++ b/src/isode/compat/bridge.c
@@ -0,0 +1,434 @@
+/* bridge.c - X.25 abstractions for TCP bridge to X25 */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by Julian Onions, Nottingham University in the UK
+ *
+ *
+ * $Log$
+ * Revision 1.1 1994/06/10 03:26:59 eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1 94/06/10 03:15:25 eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1 1994/05/31 20:33:32 eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0 91/07/17 12:17:49 isode
+ * Release 7.0
+ *
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+#include "internet.h"
+#include "tpkt.h"
+
+/* TCP/X.25 BRIDGE */
+
+#ifdef BRIDGE_X25
+
+
+static int assfd[FD_SETSIZE];
+static char bridge_inited = 0;
+
+/* */
+
+/* ARGSUSED */
+
+int start_bridge_client (local)
+struct NSAPaddr *local;
+{
+ int sd;
+ u_short port;
+ register struct servent *sp;
+
+ if ((sp = getservbyname ("x25bridge", "tcp")) == NULL)
+ port = x25_bridge_port;
+ else
+ port = sp -> s_port;
+
+ if ((sd = in_connect (x25_bridge_host, port)) == NOTOK)
+ return NOTOK;
+
+ if (write_tcp_socket (sd, "\01", 1) != 1) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("initial write"));
+
+ (void) close_tcp_socket (sd);
+ return NOTOK;
+ }
+
+ return sd;
+}
+
+/* */
+
+static int in_connect (addr, port)
+char *addr;
+u_short port;
+{
+ int sd;
+ struct sockaddr_in in_socket;
+ register struct sockaddr_in *isock = &in_socket;
+ register struct hostent *hp;
+
+ if ((hp = gethostbystring (addr)) == NULL) {
+ SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", addr));
+
+ return NOTOK;
+ }
+
+ bzero ((char *) isock, sizeof *isock);
+ isock -> sin_family = hp -> h_addrtype;
+ isock -> sin_port = port;
+ inaddr_copy (hp, isock);
+
+ if ((sd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("start_tcp_client"));
+
+ return NOTOK;
+ }
+
+ if (join_tcp_server (sd, isock) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("join_tcp_server"));
+
+ (void) close_tcp_socket (sd);
+ return NOTOK;
+ }
+
+ return sd;
+}
+
+/* */
+
+int join_bridge_server (fd, remote)
+int fd;
+register struct NSAPaddr *remote;
+{
+ if (remote != NULLNA)
+ remote -> na_stack = NA_BRG, remote -> na_community = ts_comm_x25_default;
+ if (bridge_write_nsap_addr (fd, remote, write_tcp_socket) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("write of NSAP failed"));
+
+ return NOTOK;
+ }
+
+ return fd;
+}
+
+/* */
+
+int start_bridge_server (local, backlog, opt1, opt2)
+struct NSAPaddr *local;
+int backlog,
+ opt1,
+ opt2;
+{
+ int len,
+ new,
+ sd;
+ u_short port;
+ struct servent *sp;
+ struct sockaddr_in in_socket;
+ register struct sockaddr_in *isock = &in_socket;
+
+ if (bridge_inited == 0) {
+ for (sd = 0; sd < FD_SETSIZE; sd++)
+ assfd[sd] = NOTOK;
+ bridge_inited = 1;
+ }
+ if ((sp = getservbyname ("x25bridge", "tcp")) == NULL)
+ port = x25_bridge_port;
+ else
+ port = sp -> s_port;
+
+ if ((sd = in_connect (x25_bridge_host, port)) == NOTOK)
+ return NOTOK;
+
+ if (write_tcp_socket (sd, "\02", 1) != 1) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("initial write"));
+
+ (void) close_tcp_socket (sd);
+ return NOTOK;
+ }
+
+ if (local != NULLNA)
+ local -> na_stack = NA_BRG, local -> na_community = ts_comm_x25_default;
+ if (local != NULLNA && local -> na_dtelen == 0)
+ {
+ (void) strcpy (local -> na_dte, x25_bridge_addr);
+ local -> na_dtelen = strlen(x25_bridge_addr);
+ }
+ if (local != NULLNA) {
+ DLOG (compat_log, LLOG_DEBUG,
+ ("addr", "type=%d '%s' len=%d",
+ local -> na_stack, local -> na_dte,local -> na_dtelen));
+ DLOG (compat_log, LLOG_DEBUG,
+ ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
+ local -> na_pid, local -> na_pidlen,
+ local -> na_fac, local -> na_faclen,
+ local -> na_pid, local -> na_pidlen,
+ local -> na_cudf, local -> na_cudflen));
+ }
+
+ if (bridge_write_nsap_addr (sd, local, write_tcp_socket) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("write of NSAP failed"));
+
+ (void) close_tcp_socket (sd);
+ return NOTOK;
+ }
+
+ if ((new = in_listen (backlog, opt1, opt2)) == NOTOK) {
+ (void) close_tcp_socket (sd);
+ return NOTOK;
+ }
+
+ len = sizeof *isock;
+ if (getsockname (new, (struct sockaddr *) isock, &len) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("getsockname"));
+
+out: ;
+ (void) close_tcp_socket (sd);
+ (void) close_tcp_socket (new);
+ return NOTOK;
+ }
+
+ isock -> sin_family = htons (isock -> sin_family);
+ if (write_tcp_socket (sd, (char *)isock, sizeof *isock) != sizeof *isock) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("write of sockaddr_in"));
+
+ goto out;
+ }
+ assfd[new] = sd;
+
+ return new;
+}
+
+int get_bridge_assfd(fd)
+int fd;
+{
+ if (!bridge_inited)
+ return NOTOK;
+ return assfd[fd];
+}
+
+/* */
+
+static int in_listen (backlog, opt1, opt2)
+int backlog,
+ opt1,
+ opt2;
+{
+ int sd;
+ char *cp;
+ struct sockaddr_in lo_socket;
+ register struct sockaddr_in *lsock = &lo_socket;
+ register struct hostent *hp;
+
+ if ((hp = gethostbystring (cp = getlocalhost ())) == NULL) {
+ SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", cp));
+
+ return NOTOK;
+ }
+
+ bzero ((char *) lsock, sizeof *lsock);
+ lsock -> sin_family = hp -> h_addrtype;
+ inaddr_copy (hp, lsock);
+
+ if ((sd = start_tcp_server (lsock, backlog, opt1, opt2)) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("start_tcp_server"));
+
+ return NOTOK;
+ }
+
+ return sd;
+}
+
+/* */
+
+int join_bridge_client (fd, remote)
+int fd;
+struct NSAPaddr *remote;
+{
+ int new;
+ struct sockaddr_in in_socket;
+ struct NSAPaddr sock;
+
+ if ((new = join_tcp_client (fd, &in_socket)) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("join_tcp_client"));
+
+ return NOTOK;
+ }
+
+ if (bridge_read_nsap_addr (new, &sock, read_tcp_socket) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("read of NSAP"));
+
+ (void) close_tcp_socket (new);
+ return NOTOK;
+ }
+ DLOG (compat_log, LLOG_DEBUG,
+ ("addr", "type=%d '%s' len=%d", sock.na_stack, sock.na_dte,
+ sock.na_dtelen));
+ DLOG (compat_log, LLOG_DEBUG,
+ ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
+ sock.na_pid, sock.na_pidlen,
+ sock.na_fac, sock.na_faclen,
+ sock.na_pid, sock.na_pidlen,
+ sock.na_cudf, sock.na_cudflen));
+ sock.na_stack = ntohl (sock.na_stack);
+ *remote = sock;
+ DLOG (compat_log, LLOG_DEBUG,
+ ("addr", "type=%d '%s' len=%d",
+ remote -> na_stack, remote -> na_dte,remote -> na_dtelen));
+ DLOG (compat_log, LLOG_DEBUG,
+ ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
+ remote -> na_pid, remote -> na_pidlen,
+ remote -> na_fac, remote -> na_faclen,
+ remote -> na_pid, remote -> na_pidlen,
+ remote -> na_cudf, remote -> na_cudflen));
+ return new;
+}
+
+int close_bridge_socket (sd)
+int sd;
+{
+ if (bridge_inited && assfd[sd] != NOTOK)
+ (void) close_tcp_socket (assfd[sd]);
+ assfd[sd] = NOTOK;
+ return close_tcp_socket (sd);
+}
+
+/* ARGSUSED */
+
+int bridgediscrim (na)
+struct NSAPaddr *na;
+{
+#ifndef X25
+ return 1; /* must be bridge */
+#else
+ int len = strlen (x25_bridge_discrim);
+
+ if (len == 1 && *x25_bridge_discrim == '-')
+ return 0;
+
+ return (len == 0 ? 1
+ : strncmp (na -> na_dte, x25_bridge_discrim, len) == 0);
+#endif
+}
+#endif
+
+/*
+ * Structure is as follows :-
+ * 0-1 type
+ * 2-17 dte
+ * 18 dte len
+ * 19-22 pid
+ * 23 pid len
+ * 24-39 user data
+ * 40 user data len
+ * 41-46 facilities
+ * 47 facility length
+ */
+
+int bridge_write_nsap_addr (fd, nsap, writefnx)
+int fd;
+struct NSAPaddr *nsap;
+IFP writefnx;
+{
+ u_short na_stack;
+ char buffer[50];
+
+ if (nsap == NULLNA || (na_stack = nsap -> na_stack) != NA_BRG)
+ return NOTOK;
+ na_stack = htons(na_stack);
+ bcopy ((char *)&na_stack, buffer, sizeof(na_stack));
+ bcopy (nsap -> na_dte, &buffer[2], 16);
+ buffer[18] = nsap -> na_dtelen;
+ bcopy (nsap -> na_pid, &buffer[19], 4);
+ buffer[23] = nsap -> na_pidlen;
+ bcopy (nsap -> na_cudf, &buffer[24], 16);
+ buffer[40] = nsap -> na_cudflen;
+ bcopy (nsap -> na_fac, &buffer[41], 6);
+ buffer[47] = nsap -> na_faclen;
+ if ((*writefnx) (fd, buffer, 48) != 48)
+ return NOTOK;
+ return OK;
+}
+
+static int readx ();
+
+int bridge_read_nsap_addr (fd, nsap, readfnx)
+int fd;
+struct NSAPaddr *nsap;
+IFP readfnx;
+{
+ u_short na_stack;
+ char buffer[50];
+
+ if (readx (fd, buffer, 48, readfnx) != 48)
+ return NOTOK;
+ bcopy (buffer, (char *)&na_stack, sizeof(na_stack));
+ na_stack = ntohs(na_stack);
+ if (na_stack != NA_BRG)
+ return NOTOK;
+ nsap -> na_stack = na_stack;
+ bcopy (&buffer[2], nsap -> na_dte, 16);
+ nsap -> na_dtelen = buffer[18];
+ bcopy (&buffer[19], nsap -> na_pid, 4);
+ nsap -> na_pidlen = buffer[23];
+ bcopy (&buffer[24], nsap -> na_cudf, 16);
+ nsap -> na_cudflen = buffer[40];
+ bcopy (&buffer[41], nsap -> na_fac, 6);
+ nsap -> na_faclen = buffer[47];
+ return OK;
+}
+
+static int readx (fd, buffer, n, readfnx)
+int fd;
+char *buffer;
+int n;
+IFP readfnx;
+{
+ register int i,
+ cc;
+ register char *bp;
+
+ for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) {
+ switch (cc = (*readfnx) (fd, bp, i)) {
+ case NOTOK:
+ return (i = bp - buffer) ? i : NOTOK;
+
+ case OK:
+ break;
+
+ default:
+ continue;
+ }
+ break;
+ }
+
+ return (bp - buffer);
+}