Net2/usr/src/contrib/isode/compat/norm2na.c

Compare this file to the similar file:
Show the results in this format:

/* norm2na.c - normalize NSAPaddr to NSAP struct */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/compat/RCS/norm2na.c,v 7.3 91/02/22 09:15:39 mrose Interim $";
#endif

/* 
 * $Header: /f/osi/compat/RCS/norm2na.c,v 7.3 91/02/22 09:15:39 mrose Interim $
 *
 *
 * $Log:	norm2na.c,v $
 * Revision 7.3  91/02/22  09:15:39  mrose
 * Interim 6.8
 * 
 * Revision 7.2  90/12/11  10:52:50  mrose
 * lock-and-load
 * 
 * Revision 7.1  90/08/08  14:03:02  mrose
 * stuff
 * 
 * Revision 7.0  90/08/05  16:01:25  mrose
 * *** empty log message ***
 * 
 * 
 */

/*
 *				  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 "psap.h"
#include "isoaddrs.h"
#include "tailor.h"

/* Encoding on "unrealNS" addresses based on

   	"An interim approach to use of Network Addresses",
	S.E. Kille, January 16, 1989

 */

/*  */

int	norm2na (p, len, na)
char	*p;
int	len;
struct NSAPaddr *na;
{
    na -> na_stack = NA_NSAP;

    if ((len == 8) && ((p[0] == 0x36) || (p[0] == 0x37))) {
	int	xlen;			/* SEK - X121 form */
	register char   *cp,
			*cp2,
		        *dp;
	char	nsap[14];

	dp = nsap;
	for (cp2 = (cp = p + 1) + 7; cp < cp2; cp++) {
	    register int     j;

	    if ((j = ((*cp & 0xf0) >> 4)) > 9)
		goto concrete;
	    *dp++ = j + '0';

	    if ((j = (*cp & 0x0f)) > 9) {
		if (j != 0x0f)
		    goto concrete;
	    }
	    else
		*dp++ = j + '0';
	}

	for (cp = nsap, xlen = 14; *cp == '0'; cp++, xlen--)
	    continue;
	na -> na_dtelen = xlen;
	for (cp2 = na -> na_dte; xlen-- > 0; )
		*cp2++ = *cp++;
	*cp2 = NULL;
#ifdef	BRIDGE_X25
	na -> na_stack = bridgediscrim (na) ? NA_BRG : NA_X25;
#else
	na -> na_stack = NA_X25;
#endif
	na -> na_community = SUBNET_INT_X25;
    }
    else {
	register struct ts_interim *ts,
				   *tp;

	tp = NULL;
	for (ts = ts_interim; ts -> ts_name; ts++)
	    if (len > ts -> ts_length
		    && (tp == NULL || ts -> ts_length > tp -> ts_length)
		    && bcmp (p, ts -> ts_prefix, ts -> ts_length) == 0)
		tp = ts;
	if (tp) {
	    int	    i,
		    ilen,
		    rlen;
	    register char   *cp,
			    *dp,
			    *ep;
	    char    nsap[NASIZE * 2 + 1];

	    if (tp -> ts_syntax == NA_NSAP)
		goto lock_and_load;
	    dp = nsap;
	    for (cp = p + tp -> ts_length, ep = p + len;
		     cp < ep;
		     cp++) {
		register int     j;

		if ((j = ((*cp & 0xf0) >> 4)) > 9) {
concrete: ;
		    LLOG (addr_log, LLOG_EXCEPTIONS,
			  ("invalid concrete encoding"));
		    goto realNS;
		}
		*dp++ = j + '0';

		if ((j = (*cp & 0x0f)) > 9) {
		    if (j != 0x0f)
			goto concrete;
		}
		else
		    *dp++ = j + '0';
	    }
	    *dp = NULL;

	    cp = nsap;
lock_and_load: ;
	    na -> na_community = tp -> ts_subnet;
	    switch (na -> na_stack = tp -> ts_syntax) {
		case NA_NSAP:
		    goto unrealNS;

		case NA_X25:
		    if (strlen (cp) < 1) {
			LLOG (addr_log, LLOG_EXCEPTIONS,
			      ("missing DTE+CUDF indicator: %s", nsap));
			goto realNS;
		    }
		    (void) sscanf (cp, "%1d", &i);
		    cp += 1;
		    switch (i) {
		        case 0:	/* DTE only */
			    break;

			case 1:	/* DTE+PID */
			case 2:	/* DTE+CUDF */
			    if (strlen (cp) < 1) {
				LLOG (addr_log, LLOG_EXCEPTIONS,
				      ("missing DTE+CUDF indicator: %s",
				       nsap));
				goto realNS;
			    }
			    (void) sscanf (cp, "%1d", &ilen);
			    cp += 1;
			    rlen = ilen * 3;
			    if (strlen (cp) < rlen) {
				LLOG (addr_log, LLOG_EXCEPTIONS,
				      ("bad DTE+CUDF length: %s", nsap));
				goto realNS;
			    }
			    if (i == 1) {
				if (ilen > NPSIZE) {
				    LLOG (addr_log, LLOG_EXCEPTIONS,
					  ("PID too long: %s", nsap));
				    goto realNS;
				}
				dp = na -> na_pid;
				na -> na_pidlen = ilen;
			    }
			    else {
				if (ilen > CUDFSIZE) {
				    LLOG (addr_log, LLOG_EXCEPTIONS,
					  ("CUDF too long: %s", nsap));
				    goto realNS;
				}
				dp = na -> na_cudf;
				na -> na_cudflen = ilen;
			    }
			    for (; rlen > 0; rlen -= 3) {
				(void) sscanf (cp, "%3d", &i);
				cp += 3;

				if (i > 255) {
				    LLOG (addr_log, LLOG_EXCEPTIONS,
					  ("invalid PID/CUDF: %s", nsap));
				    goto realNS;
				}
				*dp++ = i & 0xff;
			    }
			    break;

			default:
			    LLOG (addr_log, LLOG_EXCEPTIONS,
				  ("invalid DTE+CUDF indicator: %s", nsap));
			    goto realNS;
			}
		    (void) strcpy (na -> na_dte, cp);
		    na -> na_dtelen = strlen (na -> na_dte);

#ifdef	BRIDGE_X25
		    if (bridgediscrim (na))
			na -> na_stack = NA_BRG;
#endif
		    break;

		case NA_TCP:
		    if (strlen (cp) < 12) {
			LLOG (addr_log, LLOG_EXCEPTIONS,
			      ("missing IP address: %s", nsap));
			goto realNS;
		    }
		    {
			int	    q[4];

			(void) sscanf (cp, "%3d%3d%3d%3d", q, q + 1, q + 2,
				       q + 3);
			(void) sprintf (na -> na_domain,
					"%d.%d.%d.%d", q[0], q[1], q[2], q[3]);
		    }
		    cp += 12;

		    if (*cp) {
			if (strlen (cp) < 5) {
			    LLOG (addr_log, LLOG_EXCEPTIONS,
				  ("missing port: %s", nsap));
			    goto realNS;
			}
			(void) sscanf (cp, "%5d", &i);
			cp += 5;
			na -> na_port = htons ((u_short) i);

			if (*cp) {
			    if (strlen (cp) < 5) {
				LLOG (addr_log, LLOG_EXCEPTIONS,
				      ("missing tset: %s", nsap));
				goto realNS;
			    }
			    (void) sscanf (cp, "%5d", &i);
			    cp += 5;
			    na -> na_tset = (u_short) i;

			    if (*cp)
				LLOG (addr_log, LLOG_EXCEPTIONS,
				      ("extra TCP information: %s", nsap));
			}
		    }
		    break;

		default:
		    LLOG (addr_log, LLOG_NOTICE,
			  ("unknown syntax %d for DSP: %s", ts -> ts_syntax,
			   nsap));
		    goto realNS;
		}
	}
	else {
realNS: ;
	    na -> na_stack = NA_NSAP;
	    na -> na_community = SUBNET_REALNS;
unrealNS: ;
	    if (len > sizeof na -> na_address) {
		LLOG (addr_log, LLOG_EXCEPTIONS,
		      ("NSAP address too long: %d octets", len));
		return NOTOK;
	    }
	    bcopy (p, na -> na_address, na -> na_addrlen = len);
	}
    }

    return OK;
}