|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 10373 (0x2885) Types: TextFile Names: »ts2x25.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/tsap/ts2x25.c«
/* ts2x25.c - TPM: X.25 interface */ #ifndef lint static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2x25.c,v 6.1 89/03/23 22:28:14 mrose Exp $"; #endif /* * $Header: /f/osi/tsap/RCS/ts2x25.c,v 6.1 89/03/23 22:28:14 mrose Exp $ * * * $Log: ts2x25.c,v $ * Revision 6.1 89/03/23 22:28:14 mrose * out-the-door * * Revision 6.0 89/03/18 23:45:29 mrose * Release 5.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 <stdio.h> #include "tpkt.h" #ifdef X25 #include "x25.h" #include <sys/uio.h> #include <sys/ioctl.h> #include "tailor.h" static fd_set inprogress; static struct NSAPaddr **peers = NULL; extern int errno; /* \f N-CONNECT.REQUEST */ int x25open (tb, local, remote, td, async) register struct tsapblk *tb; struct NSAPaddr *local, *remote; struct TSAPdisconnect *td; { register int fd; int onoff; /* * start_x25_client does nothing with its arguments in the CAMTEC * case but there's less #ifdef code this way so... */ if ((fd = start_x25_client (local)) == NOTOK) return tsaplose (td, DR_CONGEST, "socket", "unable to start"); if (async) { if (ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)) < 0) { (void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO"); (void) close_x25_socket (fd); return NOTOK; } } tb -> tb_fd = fd; (void) XTService (tb); if (join_x25_server (fd, remote) == NOTOK) { if (async) switch (errno) { case EINPROGRESS: if (peers == NULL) { peers = (struct NSAPaddr **) calloc ((unsigned) getdtablesize (), sizeof *peers); if (peers == NULL) { (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory"); (void) close_x25_socket (fd); return (tb -> tb_fd = NOTOK); } FD_ZERO (&inprogress); } if (peers[fd] == NULL && (peers[fd] = (struct NSAPaddr *) malloc (sizeof **peers)) == NULL) { (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory"); (void) close_x25_socket (fd); return (tb -> tb_fd = NOTOK); } *(peers[fd]) = *remote; /* struct copy */ FD_SET (fd, &inprogress); return OK; case EISCONN: goto done; default: break; } (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish"); LLOG (x25_log, LLOG_NOTICE, ("connection to %s failed", na2str (remote))); (void) close_x25_socket (fd); return (tb -> tb_fd = NOTOK); } done: ; if (async) if (ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)) < 0) { (void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO"); (void) close_x25_socket (fd); return NOTOK; } (void) XTService (tb); /* in case pktsize changed... */ LLOG (x25_log, LLOG_NOTICE, ("connection %d to %s", fd, na2str (remote))); return DONE; } /* \f */ static int x25retry (tb, td) struct tsapblk *tb; struct TSAPdisconnect *td; { int onoff; int fd = tb -> tb_fd; fd_set mask; struct NSAPaddr *remote = peers[fd]; FD_ZERO (&mask); FD_SET (fd, &mask); if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1) return OK; if (!FD_ISSET (fd, &inprogress)) return DONE; if (join_x25_server (fd, remote) == NOTOK) { switch (errno) { case EINPROGRESS: return OK; case EISCONN: goto done; case EINVAL: /* UNIX bug: could be any socket errno, e.g., ETIMEDOUT */ errno = ECONNREFUSED; /* and fall */ default: break; } (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish"); FD_CLR (fd, &inprogress); (void) close_x25_socket (fd); LLOG (x25_log, LLOG_NOTICE, ("connection to %s failed", na2str (remote))); return (tb -> tb_fd = NOTOK); } done: ; (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); FD_CLR (fd, &inprogress); (void) XTService (tb); /* in case pktsize changed... */ LLOG (x25_log, LLOG_NOTICE, ("connection %d to %s", fd, na2str (remote))); return DONE; } /* \f init for read from network */ static char nsdu[MAXNSDU]; static char *np; static int bl; static int x25init (fd, t) int fd; register struct tsapkt *t; { register int cc; /* XXX: cc should be set to the maximum acceptable NSDU length. Longer NSDUs will be truncated without notification. Should be configurable (or set during N-CONNECT and remembered) */ cc = sizeof nsdu; switch (cc = read_x25_socket (fd, nsdu, cc)) { case OK: /* no data ? */ case NOTOK: #ifdef SUN_X25 if (compat_log -> ll_events & LLOG_EXCEPTIONS) (void) log_cause_and_diag(fd); #endif return DR_NETWORK; default: t -> t_length = cc + sizeof t -> t_pkthdr; break; } if (t -> t_length < TPKT_HDRLEN (t)) return DR_LENGTH; t -> t_li = nsdu[0]; t -> t_code = nsdu[1]; np = nsdu + 2; bl = t -> t_length - TPKT_HDRLEN (t); t -> t_vrsn = TPKT_VRSN; /* Not really needed! */ return OK; } /* ARGSUSED */ static int read_nsdu_buffer (fd, buffer, cc) int fd; register char *buffer; register int cc; { if (cc > bl) cc = bl; if (cc > 0) { bcopy (np, buffer, cc); np += cc, bl -= cc; } return cc; } /* \f write to network */ static int x25write (fd, t, cp, n) int fd; register struct tsapkt *t; char *cp; int n; { register int cc; register struct udvec *uv; #if defined (SUN_X25) || defined (CAMTEC_CCL) struct iovec iovs[NTPUV + 4]; register struct iovec *iov = iovs; cc = 0; iov -> iov_base = (char *) &t -> t_li; cc += (iov -> iov_len = sizeof t -> t_li); iov++; iov -> iov_base = (char *) &t -> t_code; cc += (iov -> iov_len = sizeof t -> t_code); iov++; iov -> iov_base = cp; cc += (iov -> iov_len = n); iov++; if (t -> t_vdata) { iov -> iov_base = t -> t_vdata; cc += (iov -> iov_len = t -> t_vlen); iov++; } for (uv = t -> t_udvec; uv -> uv_base; uv++) { iov -> iov_base = uv -> uv_base; cc += (iov -> iov_len = uv -> uv_len); iov++; } if (writev (fd, iovs, iov - iovs) != cc) { cc = NOTOK; #ifdef SUN_X25 if (compat_log -> ll_events & LLOG_EXCEPTIONS) (void) log_cause_and_diag(fd); #endif } else DLOG (compat_log, LLOG_DEBUG | LLOG_NOTICE, ("X.25 Write %d bytes", cc) ); #endif #ifdef UBC_X25 /* this is more generic in that it uses write_x25_socket */ char *p; cc = sizeof t -> t_li + sizeof t -> t_code + n; if (t -> t_vdata) cc += t -> t_vlen; for (uv = t -> t_udvec; uv -> uv_base; uv++) cc += uv -> uv_len; p = malloc ((unsigned) cc); cc = 0; bcopy ((char *) &t -> t_li, p + cc, sizeof t -> t_li); cc += sizeof t -> t_li; bcopy ((char *) &t -> t_code, p + cc, sizeof t -> t_code); cc += sizeof t -> t_code; bcopy (cp, p + cc, n); cc += n; if (t -> t_vdata) { bcopy (t -> t_vdata, p + cc, t -> t_vlen); cc += t -> t_vlen; } for (uv = t -> t_udvec; uv -> uv_base; uv++) { bcopy (uv -> uv_base, p + cc, uv -> uv_len); cc += uv -> uv_len; } if (write_x25_socket (fd, p, cc) != cc) { cc = NOTOK; } free (p); #endif return cc; } /* \f */ /* ARGSUSED */ char *x25save (fd, dte1, l1, dte2, l2, td) int fd; char *dte1; int l1; char *dte2; int l2; struct TSAPdisconnect *td; { static char buffer[BUFSIZ]; (void) sprintf (buffer, "%c%d %*s %*s", NT_X25, fd, l1, dte1, l2, dte2); return buffer; } int x25restore (tb, buffer, td) register struct tsapblk *tb; char *buffer; struct TSAPdisconnect *td; { int fd; char dte1[NSAP_DTELEN + 1], dte2[NSAP_DTELEN + 1]; register struct NSAPaddr *na; register struct TSAPaddr *ta; if (sscanf (buffer, "%d %s %s", &fd, dte1, dte2) != 3 || fd < 0) return tsaplose (td, DR_PARAMETER, NULLCP, "bad initialization vector \"%s\"", buffer); ta = &tb -> tb_initiating; ta -> ta_naddr = 1; na = ta -> ta_addrs; na -> na_type = NA_X25; bcopy(dte1, na -> na_dte, strlen(dte1)); na -> na_dtelen = strlen (na -> na_dte); tb -> tb_fd = fd; (void) XTService (tb); ta = &tb -> tb_responding; ta -> ta_naddr = 1; na = ta -> ta_addrs; na -> na_type = NA_X25; bcopy(dte2, na -> na_dte, strlen(dte2)); na -> na_dtelen = strlen (na -> na_dte); #ifdef SUN_X25 (void) set_x25_facilities (tb -> tb_fd, -1, "Negotiated"); #endif return OK; } /* \f */ int XTService (tb) register struct tsapblk *tb; { int maxnsdu = MAXNSDU; tb -> tb_flags |= TB_X25; #ifdef notyet if (recvpktsize > DT_MAGIC && recvpktsize < maxnsdu) maxnsdu = recvpktsize; if (sendpktsize > DT_MAGIC && sendpktsize < maxnsdu) maxnsdu = sendpktsize; #endif tb -> tb_tsdusize = maxnsdu - (tb -> tb_tpduslop = DT_MAGIC); tb -> tb_retryfnx = x25retry; tb -> tb_initfnx = x25init; tb -> tb_readfnx = read_nsdu_buffer; tb -> tb_writefnx = x25write; tb -> tb_closefnx = close_x25_socket; tb -> tb_selectfnx = select_x25_socket; tp0init (tb); } #endif