|
|
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 x
Length: 12285 (0x2ffd)
Types: TextFile
Names: »x25addr.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/compat/x25addr.c«
/* x25addr.c - X.25 level generic <-> interface address munging */
#ifndef lint
static char *rcsid = "$Header: /f/osi/compat/RCS/x25addr.c,v 7.2 89/12/11 16:21:42 mrose Exp $";
#endif
/*
* $Header: /f/osi/compat/RCS/x25addr.c,v 7.2 89/12/11 16:21:42 mrose Exp $
*
* Contributed by George Michaelson, Julian Onions, and John Pavel
*
*
* $Log: x25addr.c,v $
* Revision 7.2 89/12/11 16:21:42 mrose
* comments
*
* Revision 7.1 89/12/11 01:36:14 mrose
* SUN_X25_HACK
*
* Revision 7.0 89/11/23 21:23:49 mrose
* Release 6.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 */
/*
* for *really* generic address translation
*/
#include <errno.h>
#include <stdio.h>
#include "general.h"
#include "manifest.h"
#ifdef X25
#include "tailor.h"
#include "tpkt.h"
#include <sys/file.h>
#include "x25.h"
#ifndef DEBUG
#define DEBUG
#endif
/* \f
*/
/*
* convert from the generic X25 structure to interface specific
*/
/* ARGSUSED */
CONN_DB *gen2if (generic, specific, context)
struct NSAPaddr *generic;
CONN_DB *specific;
int context;
{
int dtelen;
char dte[NSAP_DTELEN + 1];
#ifdef CAMTEC_CCL
struct iovec *iov;
#endif
if (generic == NULLNA
|| specific == (CONN_DB *) 0
|| generic -> na_type != NA_X25)
return (CONN_DB *)0;
if (x25_dnic_prefix && *x25_dnic_prefix) {
/* need DNIC on local calls? */
register int i;
if ( strncmp(generic -> na_dte, x25_dnic_prefix,
i = strlen(x25_dnic_prefix)) == 0 )
{
if (x25_strip_dnic) bcopy(generic -> na_dte + i, dte, dtelen =
generic -> na_dtelen - i);
else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen);
}
else
if (x25_intl_zero)
{
bcopy(generic -> na_dte, dte + 1, dtelen = generic-> na_dtelen);
*dte = '0', dtelen++;
}
else bcopy(generic -> na_dte, dte, dtelen = generic -> na_dtelen);
}
else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen);
dte[dtelen] = NULL;
#ifdef SUN_X25_HACK
/*
* If your X.25 provider expects to receive the subaddress alone
* on listen requests, and you are using SunLink X.25, you may need
* to enable SUN_X25_HACK in your config file. This will allow you
* to use x25_local_dte in isotailor to specify a dte mask to be
* stripped when listening, and thus use full DTE strings in
* isoentities and QUIPU EDB files. You will also have to use the
* tsapd -a <dte> option to specify the listen address in
* /etc/rc.local and other tsapd startups since by default this equals
* x25_local_dte and thus will be masked to <null> unless overridden
* with full DTE + subaddress.
*/
/*
* in ADDR_LISTEN context, it may be neccessary to only listen
* on the sub-address, because certain PTT-provided networks
* remove the local DTE from incoming CR packets.
*
* SunLink X.25 listen asserts whatever DTE it is given as a simple
* string-compare, and will never receive inbound calls that bear
* only the sub-address if you assert the full DTE.
*
* this behaviour is orthogonal to any requirements to remove DNIC
* or add a leading 0 on outbound calls, and so needs a separate
* test. It uses tailor variable x25_local_dte to assert the local
* DTE *without* subaddress which should be tested for and stripped
* when detected.
*/
if ((context == ADDR_LISTEN) && x25_local_dte && *x25_local_dte)
{
register int i;
if ( strncmp(generic -> na_dte, x25_local_dte,
i = strlen(x25_local_dte)) == 0 )
{
bcopy(generic -> na_dte + i, dte, dtelen =
generic -> na_dtelen - i);
dte[dtelen] = NULL;
}
}
#endif
DLOG (x25_log, LLOG_DEBUG,
("gen2if %s -> %s, %d octets; PID %s",
generic -> na_dte, dte, dtelen,
sel2str (generic -> na_pid, (int) generic -> na_pidlen,1)));
#ifndef CAMTEC_CCL
bzero ((char *)specific, sizeof *specific);
#endif
#ifdef UBC_X25
if ((specific -> xaddr_len = dtelen) != 0) {
bcopy (dte, specific -> xaddr_addr,
dtelen);
specific -> xaddr_len = dtelen;
specific -> xaddr_facilities = 0;
bcopy (generic -> na_pid, specific -> xaddr_proto,
generic -> na_pidlen);
bcopy (generic -> na_cudf, specific -> xaddr_userdata,
generic -> na_cudflen);
}
#endif
#ifdef SUN_X25
specific -> hostlen = char2bcd (dte, specific -> host);
/* Zero PID */
if (generic -> na_pidlen) { /* non-null PID */
if (generic -> na_pidlen > NPSIZE) {
SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
("PID too long (%d > %d)", generic -> na_pidlen, NPSIZE));
return (CONN_DB *)0;
} else {
bzero((char *)specific -> data, NPSIZE);
bcopy (generic -> na_pid, (char *)specific -> data,
generic -> na_pidlen);
bcopy (generic -> na_cudf, (char *) specific -> data + NPSIZE,
generic -> na_cudflen);
specific -> datalen = generic -> na_pidlen + generic -> na_cudflen;
}
} else { /* Null PID (just copy in CUDF, the first four octets of which
will be the PID in any case) */
bcopy (generic -> na_cudf, (char *)specific -> data,
generic -> na_cudflen);
specific -> datalen = generic -> na_cudflen;
}
#endif
#ifdef CAMTEC_CCL
switch (context) {
case ADDR_REMOTE:
iov = &(specific -> ccl_iovec[0]);
if (x25_outgoing_port == '#') {
char *a, *b;
int i;
iov -> iov_len = dtelen + 4;
bzero(iov -> iov_base, iov -> iov_len + 1);
a = iov -> iov_base;
b = dte;
*a++ = '#';
*a++ = '[';
for (i = 0; i < dtelen; i++) {
if (i == 2) *a++ = ':';
else if (i == 14) *a++ = ']';
*a++ = *b++;
}
}
else {
iov -> iov_len = dtelen+1;
bcopy(dte, (iov -> iov_base)+1, dtelen);
*(iov -> iov_base) = x25_outgoing_port;
}
break;
case ADDR_LOCAL:
iov = &(specific -> ccl_iovec[0]);
strncpy(iov -> iov_base, generic -> na_dte, generic -> na_dtelen);
iov -> iov_base[generic -> na_dtelen] = '\0';
return (specific);
case ADDR_LISTEN:
iov = &(specific -> ccl_iovec[0]);
if (generic -> na_pidlen)
{ /* listen on a PID */
register int i;
iov -> iov_base[0] = 'C';
bcopy(generic -> na_pid, iov -> iov_base + 1,
i = generic -> na_pidlen);
iov -> iov_len = i + 1;
}
else
if (generic -> na_dtelen < 6)
{ /* listen on a subaddress */
register int i;
iov -> iov_base[0] = 'S';
bcopy(generic -> na_dte, iov -> iov_base + 1,
i = generic -> na_dtelen);
iov -> iov_len = i + 1;
}
else /* full DTE */
bcopy(dte, iov -> iov_base,
iov -> iov_len = dtelen);
return (specific);
}
/*
* CUDF & PID must be merged. malloc initailly PIDsize space
* and bzero it. this may be UK net specific action which
* ensures we do NOT fall foul of listeners which use pid
* to match as well as "true" cudf & DTE.
*/
(iov = &(specific -> ccl_iovec[2])) -> iov_len = 0;
if (generic -> na_faclen != 0)
bcopy (generic -> na_fac, iov -> iov_base,
iov -> iov_len = min( generic -> na_faclen, FACSIZE) );
iov++;
if ( (iov -> iov_len = generic -> na_pidlen) != 0)
bcopy (generic -> na_pid, iov -> iov_base, generic -> na_pidlen);
/*
* if there is any other user data add that in now...
* actually cudf is a variable length field so this is
* all very suspect.
*/
if (generic -> na_cudflen != 0)
bcopy(generic -> na_cudf, iov -> iov_base + iov -> iov_len,
generic -> na_cudflen), iov -> iov_len += generic -> na_cudflen;
#endif
return(specific);
}
/* \f
*/
/*
* convert from interface specific format to generic X.25 structure
*/
/* ARGSUSED */
struct NSAPaddr *if2gen (generic, specific, context)
struct NSAPaddr *generic;
CONN_DB *specific;
int context;
{
int dtelen;
char dte[NSAP_DTELEN + 1];
#ifdef CAMTEC_CCL
struct iovec *iov;
#endif
if (generic == NULLNA || specific == (CONN_DB *) 0)
return NULLNA;
bzero ((char *)generic, sizeof *generic);
bzero (dte, sizeof dte);
dtelen = 0;
generic -> na_type = NA_X25;
generic -> na_subnet = ts_comm_x25_default;
#ifdef UBC_X25
if (specific -> xaddr_len != 0) {
bcopy (specific -> xaddr_addr, dte, specific -> xaddr_len);
dtelen = specific -> xaddr_len;
bcopy (specific -> xaddr_proto, generic -> na_pid,
sizeof(specific -> xaddr_proto));
generic -> na_pidlen = sizeof specific -> xaddr_proto;
bcopy (specific -> xaddr_userdata, generic -> na_cudf,
sizeof(specific -> xaddr_userdata));
generic -> na_cudflen = sizeof specific -> xaddr_userdata;
}
#endif
#ifdef SUN_X25
dtelen = bcd2char (specific -> host, dte, (int) specific -> hostlen);
if (specific -> datalen > NPSIZE) { /* have some real user data after the PID */
bcopy((char *)specific -> data, generic -> na_pid,
generic -> na_pidlen = NPSIZE);
bcopy((char *) specific -> data + generic -> na_pidlen,
generic -> na_cudf,
generic -> na_cudflen = specific -> datalen - generic -> na_pidlen);
}
else { /* PID only */
bcopy((char *)specific -> data, generic -> na_pid,
generic -> na_pidlen = specific -> datalen);
generic -> na_cudflen = 0;
}
#endif
#ifdef CAMTEC_CCL
switch (context) {
case ADDR_REMOTE:
iov = &(specific -> ccl_iovec[1]);
if (iov -> iov_len) {
if (*(iov->iov_base) == '#') {
char *a;
a = iov -> iov_base;
while (*a && iov -> iov_len) {
if (*a == ']') {
iov -> iov_len--;
a++;
break;
}
iov -> iov_len--;
a++;
}
if (*a == 0 || iov -> iov_len == 0)
dtelen = 0;
else {
dtelen = iov -> iov_len;
bcopy (a, dte, dtelen);
}
}
else {
dtelen = iov -> iov_len - 1;
bcopy ((iov -> iov_base)+1, dte,
dtelen);
}
}
else dtelen = 0;
break;
case ADDR_LOCAL:
iov = &(specific -> ccl_iovec[0]);
if (iov -> iov_len) {
dtelen = iov -> iov_len -1;
bcopy ((iov -> iov_base)+1, dte,
dtelen);
}
else dtelen = 0;
break;
case ADDR_LISTEN:
return NULLNA;
}
if ( (iov = &(specific -> ccl_iovec[2])) -> iov_len )
bcopy( iov -> iov_base, generic -> na_fac,
generic -> na_faclen = min( iov -> iov_len, FACSIZE));
if ( ++iov -> iov_len)
{
bcopy( iov -> iov_base, generic -> na_pid,
generic -> na_pidlen = min( iov -> iov_len, NPSIZE));
if ( iov -> iov_len > NPSIZE)
bcopy( iov -> iov_base + NPSIZE, generic -> na_cudf,
generic -> na_cudflen = min(iov -> iov_len - NPSIZE, CUDFSIZE));
}
#endif
if (x25_dnic_prefix && *x25_dnic_prefix) {
register int i;
i = 0;
if (x25_intl_zero && dte[0] == '0' && dte[1] != '0')
i = 1;
else
if (x25_dnic_prefix
&& *x25_dnic_prefix
&& x25_strip_dnic
&& dtelen < 12) /* local call... */
bcopy (x25_dnic_prefix, generic -> na_dte,
generic -> na_dtelen = strlen (x25_dnic_prefix));
bcopy (dte + i, generic -> na_dte + generic -> na_dtelen, dtelen - i);
generic -> na_dtelen += dtelen - i;
}
else
bcopy (dte, generic -> na_dte, generic -> na_dtelen = dtelen);
DLOG (x25_log, LLOG_DEBUG,
("if2gen %s -> %s, %d octets; PID %s",
dte, generic -> na_dte, generic -> na_dtelen,
sel2str (generic -> na_pid, (int) generic -> na_pidlen,1)));
return(generic);
}
/* \f
*/
#ifdef SUN_X25
static int char2bcd (s, d)
register char *s;
register u_char *d;
{
register int c,
i;
for (i = 0; *s; i++) {
if ((c = *s++) >= 'a' && c <= 'f')
c -= 'a' + 0x0a;
else
if (c >= 'A' && c <= 'F')
c -= 'A' + 0x0a;
else
if (c >= '0' && c <= '9')
c -= '0';
else
c = 0;
if (i & 1)
*d++ |= c & 0xf;
else
*d = (c & 0xf) << 4;
}
return i;
}
/* \f
*/
static int bcd2char (s, d, len)
register u_char *s;
register char *d;
int len;
{
register int i,
g;
for (i = 0; i < len; i++) {
g = s[i >> 1];
if ((i & 1) == 0)
g >>= 4;
g &= 0xf;
if (g < 0x0a)
*d++ = g + '0';
else
*d++ = g + 'a' - 0x0a;
}
*d = NULL;
return len;
}
#endif
#endif