|
|
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