From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP  8-OCT-1988 03:45
To:	ARISIA::EVERHART
Subj:	RE: Information Needed on DECNet


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Fri,  7 OCT 88 22:40:29 PDT
Received: from utadnx.cc.utexas.edu by KL.SRI.COM with TCP; Fri, 7 Oct 88 22:20:32 PDT
Date: 8 Oct 88 00:12:00 CDT
From: "Rick Watson" <ccaw001@utadnx.cc.utexas.edu>
Subject: RE: Information Needed on DECNet
To: "asuvax!nud!mcdchg!ditka!cocktrice!mdm" <asuvax!nud!mcdchg!ditka!cocktrice!mdm@noao.edu>
cc: <info-vax@kl.sri.com>

> From: asuvax!nud!mcdchg!ditka!cocktrice!mdm@noao.edu  (Mike Mitchell)

> [...]
> I have a piece of equipment that I would like to hook up to ethernet and
> get it to speak to a Vax running VMS. It would seem to me that a nice
> way to do this would be to get the equipment to speak DECNet, but I am
> not sure what this intails.

> Specifically, I am interested in how DECNet packets are formed, what kind
> of information is contained in them and how to get things to communicate.
> What would be ideal is talking to an ethernet controller card in the VAX
> and not worry about the VMS/DECNet stuff at all, however in my past experience
> I would guess that VMS would be very uncoprative at this level.

Actually, it is quite easy to read/write ethernet packets.  See the
I/O User's Manual for complete details.  Here's a little bit of code
to get you started.  Disclaimer: this code was quick and dirty. It is
incomplete and somewhat poorly written, but it should, along with the
manual, get you started.  Implementing your own DECnet protocols would
be a difficult task. 

Rick Watson
University of Texas Computation Center
 arpa:   watson@utadnx.cc.utexas.edu (128.83.1.26)
 uucp:   ...seismo!cs.utexas.edu!ut-emx!rick
 bitnet: watson@utadnx
 span:   utspan::watson (UTSPAN is 25.128)
 phone:  512/471-8220 512/471-3241

#include <descrip.h>
#include <stdio.h>
#include <iodef.h>

#define NMA$C_PCLI_PTY 0xb0e		/* protocol type */
#define NMA$C_PCLI_PRM 0xb18		/* Promiscuous mode */
#define NMA$C_STATE_ON 0		/* Promiscuous mode enabled */
#define NMA$C_STATE_OFF 1		/* Promiscuous mode disabled */
#define NMA$C_PCLI_BFN 0x451		/* Number of receive buffers */
#define NMA$C_PCLI_BUS 0xaf1		/* Max rcv buffer size */
#define NMA$C_PCLI_PHA 0xb04		/* Physical port address */
#define NMA$C_LINMC_SET 1		/* Set PHA */
#define NMA$C_LINMC_CLR 2		/* Clear PHA */
#define NMA$C_LINMC_SDF 4		/* set PHA to default decnet */
#define NMA$C_PCLI_PAD 0xB1A		/* Padding on transmit messages */
#define NMA$C_PCLI_HWA 0x488		/* hardware address */
#define NMA$C_PCLI_EKO 0xB1F		/* Echo Mode */
#define NMA$C_CTLIN_LBE 0x411		/* Local buffer errors counter */
#define NMA$C_CTLIN_OVR 0x428		/* Overrun counter */

typedef short word;

int stat;
word chan;
word iosb[4];
unsigned char buf[1500];

/**	openether - open the ethernet device.
*/
openether(device)
char *device;				/* name of ethernet device */
					/* e.g.: XEA0:             */
{
	struct {
		word	BFN;
		long	BFN_VAL;
		word	PTY;
		long	PTY_VAL;
		word	BUS;
		long	BUS_VAL;
		word	PAD;
		long	PAD_VAL;
		word	PRM;
		int	PRM_VAL;
	} StartupBuf = {NMA$C_PCLI_BFN, 2,		/* number of buffers */
			NMA$C_PCLI_PTY, 0x1234,		/* ether type, watch for network order! */
			NMA$C_PCLI_BUS, 1500,		/* max buffer size */
			NMA$C_PCLI_PAD, NMA$C_STATE_OFF,/* No pad */
			NMA$C_PCLI_PRM, NMA$C_STATE_ON /* promiscuous */
	};
	struct {
		int	size;
		int	addr;
	} StartupBufDes = {sizeof (StartupBuf), &StartupBuf};
	struct dsc$descriptor_s devd = 
		{ strlen(device), DSC$K_DTYPE_T, DSC$K_CLASS_S, device};

/*  assign the device */

	stat = sys$assign(&devd, &chan, 0, 0);
	if (!(stat & 1)) lib$stop(stat);

/*  start the controller */

	stat = sys$qiow(0, chan, IO$_SETMODE + IO$M_STARTUP + IO$M_CTRL,
		iosb, 0, 0,
		0, &StartupBufDes, 0, 0, 0, 0);
	if (!(stat & 1)) lib$stop(stat);
	if ((iosb[0] & 1) != 1) {
		printf("startup failed, iosb = 0x%x %x %x %x\n", 
			iosb[0], iosb[1], iosb[2], iosb[3]);
		exit(1);
	}
}


/**	readether - read a packet off the ethernet.
*/
readether()
{
	/* read such the ether header (dst, src, type) and data  */
	/* come out contiguous in the buffer                     */

	stat = sys$qiow(0, chan, IO$_READLBLK, iosb, 0, 0,
		&buf[14], sizeof(buf)-14, 0, 0,
		&buf[0], 0);
	if (!(stat & 1)) lib$stop(stat);
	if (iosb[0] != 1) {
		fprintf(stderr, "iosb = %x %x %x %x\n", iosb[0], iosb[1], 
			iosb[2], iosb[3]);
		lib$stop(iosb[0]);
	}
	return iosb[1] + 14;			/* return byte count */
}


