From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 19-DEC-1989 05:13
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Re: Node name <-> address translation

Message-Id:  <8912191008.AA18381@crdgw1.ge.com>
Received: From NSFNET-RELAY.AC.UK by CRVAX.SRI.COM with TCP; Tue, 19 DEC 89 01:37:15 PDT
Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK 
           via Janet with NIFTP  id aa01601; 19 Dec 89 9:25 GMT
Date:           Tue, 19 Dec 89   9:29 BST
From: Nick de Smith <"PSI%JANET.000000000040::NICK%ncdlab.ulcc.ac.uk"@NSFnet-Relay.AC.UK>
To: INFO-VAX <@NSFnet-Relay.AC.UK:INFO-VAX@crvax.sri.com>
Subject:        Re: Node name <-> address translation

From: "Nick de Smith, Special Systems Group, Applied Telematics" <NICK@NCDLAB.ULCC.AC.UK>
Organization: Applied Telematics Group Ltd.
Sender: nick@ncdlab.ulcc.ac.uk

Hi,

Again, this may be too late (we are still a week behind in the UK).

It is easy to use the NICE protocol via NMLSHR, if you have the manuals :->

The manual needed is "DNA Phase IV Network Management Functional Specification"
(AA-X437A-TK). This is quite possibly the most diabolically obscure piece of DEC
documentation you may ever set eyes on, with the possible exception of the MOP
manual (AA-X436A-TK).

Enclosed is a simple example that converts node names to numbers and vica versa.
It will also list all know nodes.

Note that NICE (Network Informtion and Control Exchange) is a declining protocol
and will be replaced by CMIP (Common Management Infomation Protocol) under
DECnet Phase V. For more information on CMIP see "DECnet DIGITAL Network
Architecture (Phase V)" EK-DNAPV-GD, Chapter 10. This manual is a *very good*
introduction to Phase V, even if it contains some errors (which DEC manual
doesn't?). NICE should be "supported for compatability with Phase IV nodes only"
for some time after Phase V is established.

regards,

nick	NICK@NCDLAB.ULCC.AC.UK

NETNAME.COM

$ CC /Debug NETNAME
$ Link NETNAME,SYS$INPUT/Option
SYS$SHARE:NMLSHR/Share
SYS$SHARE:VAXCRTL/Share
$!

NETNAME.C:

/*****************************************************************************************************************

 Program :	NETNAME		Example interface to NML using NMLSHR
 Module	:	NETNAME.C	(the root)
 Author	:	Nick de Smith	May 1986
		Applied Telematics Services, 7 Vale Avenue, Tunbridge Wells, Kent TN1 1DJ, England.
		NICK@NCDLAB.ULCC.AC.UK, PSI%234213300154::NICK

 This is a simple example interface to NML via NMLSHR. It uses the documented NICE message from the DEC manual
 "DNA Phase IV Network Management Functional Specification" (AA-X437A-TK). To understand NICE you MUST have a
 copy of this manual.
 All this program does is to extract node name and address information from the local node's databases.

 Edit	Edit date	By	Reason
  01	21-Jul-86	NMdS	First attempt

*****************************************************************************************************************/

#module		NETNAME		"V1.01"

#include	descrip							/* Define DSC$xxx - VAX descriptors	*/
#include	ssdef							/* Define SS$xxxx - System status codes	*/
#include	stsdef							/* Define STS$M_xxxx - VMS status bits	*/

#include	stdio


/*****************************************************************************************************************

						N E T N A M E

 This program returns node name and address information from the local node's database given a node address, a
 node name of a request for a list of all nodes.

*****************************************************************************************************************/

NETNAME()
{
	long	status;
	long	callback_routine();					/* Name of routine to service NML callbacks */
	long	node_address;
	struct	nml_command {
		unsigned	nml_function	: 8;
		unsigned	nml_option	: 8;
		unsigned	nml_entity_id	: 8;
		variant_union {
			short	nml_node_address   ;
			char	nml_node_name[ 6 + 1 ] ;
		} a;
	} nml_command;
	struct dsc$descriptor_d nml_command_desc = {
		0, DSC$K_DTYPE_T, DSC$K_CLASS_S, &nml_command };

	nml_command.nml_function	= 20;				/* Read information			*/
	nml_command.nml_option		= 0;				/* Option: <7)	 0 = volatile (database) */
									/*	   <4:6> 0 = summary (information type)	*/
									/*	   <0:2> 0 = Entity is node	*/
	printf("Enter node address (1024*area+address), -1 for all nodes, or\n" );
	printf("type -2 to specify a node by name\n\n" );

	printf("* Node : "); fflush(stdout); scanf("%d",&node_address );
	if ( node_address >= 0 ) {					/* Node address specified		*/
		nml_command.nml_entity_id	= 0;			/* Node specification format is node address */
		nml_command.nml_node_address	= node_address;		/* Node address (zero = executor)	*/
		nml_command_desc.dsc$w_length	= 5;			/* 5 byte command			*/
	} else if ( node_address == -1 ) {				/* -1 means all (known) nodes		*/
		nml_command.nml_entity_id	= -1;			/* Known nodes				*/
		nml_command_desc.dsc$w_length	= 3;			/* 3 byte command			*/
	} else {
		printf("Node name: "); fflush(stdout); scanf("%s", nml_command.nml_node_name );
		nml_command.nml_entity_id	= strlen( nml_command.nml_node_name );
		nml_command_desc.dsc$w_length	= 3 + strlen( nml_command.nml_node_name );
	}

	status = NML$INITIALIZE();					/* Set up our interface to NML		*/
	if ( (status & STS$M_SUCCESS) == 0 ) {
		SYS$EXIT( status );
	}

	status = NML$PROCESS_NICE(					/* Start processing the NICE command	*/
		&nml_command_desc	,				/* NML command				*/
		callback_routine	);				/* Name of routine to process callbacks from NML */

	status = NML$TERMINATE();					/* Finish with NML			*/

	return status;							/* Return final status to caller	*/
}


/*****************************************************************************************************************

					c a l l b a c k _ r o u t i n e

 This routine is called whenever there is an item of information to process from NML. It is passed the descriptor
 of the item. The item contents depends on what data we asked for.

*****************************************************************************************************************/
static
callback_routine(
	struct dsc$descriptor *nml_reply	)			/* Reply from NML to process		*/
{
	typedef struct	nml_data {
		char		ret_status	;
		short		err_detail	;
		unsigned	err_message_len	: 8;
		variant_union {
			short	node_number	;
			char	err_message	;
		} a;
		unsigned	node_name_len	: 8;
		char		node_name[ 6 ]	;
	} NML_DATA, *NML_DATA_PTR;
/*
	printf( "Number of bytes returned = %d.\n", nml_reply->dsc$w_length );
	LIB$PUT_OUTPUT( nml_reply );
*/
#define	nml_ptr ((NML_DATA_PTR) nml_reply->dsc$a_pointer)
	switch ( nml_ptr->ret_status ) {
		case 1:							/* Last part of multiple response or only part of single */
		case 3:							/* Section of multiple response, more follows */
			printf( " %d.%d\t%.*s%s\n", nml_ptr->node_number / 1024, nml_ptr->node_number % 1024 ,
				nml_ptr->node_name_len & 127, nml_ptr->node_name,
				nml_ptr->node_name_len & 128 ? " (executor)" : "" );
			break;
		case 2:							/* Multiple response stream accepted	*/
			break;
		case -128:						/* End of multiple response stream	*/
			break;
		default:						/* Something unexpected			*/
			printf( "NML error return status, %d.\n", nml_ptr->ret_status );
			if ( nml_ptr->err_detail != 0xFFFF ) {		/* If there was a system error number... */
				printf( "System dependant error detail, 0x%04X\n", nml_ptr->err_detail );
			}
			if ( nml_ptr->err_message_len != 0 ) {		/* If there was an error message...	*/
				printf( " Error message, \"%.*s\"\n", nml_ptr->err_message_len, &nml_ptr->err_message );
			}
			break;
	}
	return	SS$_NORMAL;						/* Must always return success to caller	*/
}


