From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 27-JAN-1989 07:48
To:	MRGATE::"ARISIA::EVERHART"
Subj:	ethernet address.


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu, 26 JAN 89 14:09:38 PDT
Received: from bu-it.BU.EDU by KL.SRI.COM with TCP; Thu, 26 Jan 89 13:55:21 PST
Received: by bu-it.BU.EDU (5.58/4.7)
	id AA22212; Thu, 26 Jan 89 16:51:52 EST
Date: Thu, 26 Jan 89 16:51:52 EST
From: gjc@bu-it.BU.EDU (George J. Carrette)
Message-Id: <8901262151.AA22212@bu-it.BU.EDU>
To: info-vax@kl.sri.com
Subject: ethernet address.

The following code will get the HWA, which is the actually ROM hardware
ethernet address. In order to find out what the decnet assigned
so-called "physical" ethernet, or PHA is, you need to first do a setmode
on the assigned device channel. See the DEUNA/DEQUNA device-driver
manual for more information. Thanks to Dave Kashtan for setting
me straight on the strange parsing needed on the return value of
sensemode.

/* Display basic site-related information 
 * 21-DEC-88 George Carrette, Mitech Corporation, 508-371-2002
   74 Junction Square, Concord MA 01742
 */
 


#include <stdio.h>

char *decode_cpu();

main()
{int retval;
 unsigned char eaddr[6];
 long days,cpu,sn,sid;
 if (get_eaddr_hwa(&eaddr,&days,&cpu,&sn,&sid))
   printf("%X%X-%X%X-%X%X-%X%X-%X%X-%X%X\n",
	  eaddr[0]>>4,eaddr[0]&0xF,
	  eaddr[1]>>4,eaddr[1]&0xF,
	  eaddr[2]>>4,eaddr[2]&0xF,
	  eaddr[3]>>4,eaddr[3]&0xF,
	  eaddr[4]>>4,eaddr[4]&0xF,
	  eaddr[5]>>4,eaddr[5]&0xF);
 else
   printf("could not get hardware ethernet address\n");
 printf("%d days since Nov 17, 1858\n",days);
 printf("CPU = %d (%s)\n",cpu,decode_cpu(cpu));
 printf("SID = %x\n",sid);
 printf("SN  = %X\n",sn);}
 
#include <descrip.h>
#include <ssdef.h>
#include <iodef.h>
#include <string.h>

globalvalue SYI$_SID;

/* NMA codes from
 $lib/extract=$nmadef sys$library:lib.mlb
*/

#define NMA$C_PCLI_HWA 1160
#define NMA$C_PCLI_PHA 2820

/* DC and DT codes from
 $lib/extract=$dcdef sys$library:starlet.mlb
*/

#define DC$_SCOM	32
#define DT$_DEUNA	14
#define DT$_DEQNA	22
#define DT$_ES_LANCE	24
#define DT$_DELUA	25
#define DT$_ET_DEBNA	29
#define DT$_XQ_DELQA	33


int get_eaddr_hwa(eaddr,days,cpu,sn,sid)
     char *eaddr;long *days,*cpu,*sn,*sid;
{int fcn,efn,retval,mode,dn,opcode,clength,litem;
 short chan; long code;
 struct sense_iosb
   {unsigned short cstatus;
    unsigned short tsize;
    unsigned char unused1;
    unsigned char status;
    unsigned char errors;
    unsigned char unused2;} iosb;
 struct sense_p1
   {unsigned char class;
    unsigned char type;
    unsigned short max_message_size;
    unsigned char unused1;
    unsigned char status;
    unsigned char error_summary;
    unsigned char unused2;
    char extra_safe[100];} p1;
 struct dsc$descriptor devnam,p2;
 char buffer[512],*cp,*dev,*citem,*devst;
 lib$day(days,0,0);
 code = SYI$_SID;
 lib$getsyi(&code,sid,0,0,0,0);
 *cpu = ((*sid >> 24) & 0xFF);
 switch(*cpu)
   {case 1: /* 780 */
      *sn = *sid & 0x7FFF;
      break;
    case 4: /* 8600 */
    case 6: /* 8800 */
      *sn = *sid & 0xFFFF;
      break;
    default:
      *sn = 0;}
 for(devst="XEA0:ESA0:XQA0:ETA0:"; *devst; devst += 5)
   {devnam.dsc$w_length = 5;
    devnam.dsc$a_pointer = devst;
    devnam.dsc$b_class = DSC$K_CLASS_S;
    devnam.dsc$b_dtype = DSC$K_DTYPE_T;
    mode = 0;
    retval = sys$assign(&devnam,&chan,mode,0);
    if ((retval != SS$_NORMAL) && (retval != SS$_REMOTE)) continue;
    fcn = IO$_SENSEMODE | IO$M_CTRL;
    efn = 0;
    retval = sys$qiow(efn,chan,fcn,&iosb,0,0,&p1,0,0,0,0,0);
    if (retval == SS$_NORMAL) retval = iosb.cstatus;
    if (retval != SS$_NORMAL) {sys$dassgn(chan); continue;}
    if ((p1.class != DC$_SCOM) ||
	((p1.type != DT$_DEUNA) && (p1.type != DT$_DEQNA) &&
	 (p1.type != DT$_ES_LANCE) && (p1.type != DT$_DELUA) &&
	 (p1.type != DT$_ET_DEBNA) && (p1.type != DT$_XQ_DELQA)))
      {sys$dassgn(chan); continue;}
    p2.dsc$w_length = sizeof(buffer);
    p2.dsc$a_pointer = &buffer;
    p2.dsc$b_class = 0;
    p2.dsc$b_dtype = 0;
    retval = sys$qiow(efn,chan,fcn,&iosb,0,0,&p1,&p2,0,0,0,0);
    if (retval == SS$_NORMAL) retval = iosb.cstatus;
    if (retval != SS$_NORMAL) {sys$dassgn(chan); continue;}
    sys$dassgn(chan);
    cp = buffer;
    dn = 0;
    while (dn < iosb.tsize)
      {opcode = *((short *)cp);
       cp += sizeof(short);
       dn += sizeof(short);
       if (opcode & 0x1000)
	 {clength = *((short *)cp);
	  cp += sizeof(short);
	  dn += sizeof(short);
	  citem = cp;
	  cp += clength;
	  dn += clength;}
       else
	 {litem = *((long *)cp);
	  cp += sizeof(long);
	  dn += sizeof(long);}
       switch (opcode & 0xFFF)
	 {case NMA$C_PCLI_PHA:
	    break;
	  case NMA$C_PCLI_HWA:
	    memcpy(eaddr,citem,clength);
	    return(1);}}}
 return(0);}


/* lib/extract=$prdef sys$library:starlet.mlb */

#define	PR$_SID_TYP780	1
#define	PR$_SID_TYP750	2
#define	PR$_SID_TYP730	3
#define	PR$_SID_TYP790	4
#define	PR$_SID_TYP8SS	5
#define	PR$_SID_TYP8NN	6
#define	PR$_SID_TYPUV1	7
#define	PR$_SID_TYPUV2	8
#define	PR$_SID_TYP009	9
#define	PR$_SID_TYP650	10
#define	PR$_SID_TYP9RR	11
#define PR$_SID_TYP8PS	17

char *decode_cpu(n)
     long n;
{if(n == PR$_SID_TYP780) return("780");
 if(n == PR$_SID_TYP750) return("750");
 if(n == PR$_SID_TYP730) return("730");
 if(n == PR$_SID_TYP790) return("790");
 if(n == PR$_SID_TYP8SS) return("8SS");
 if(n == PR$_SID_TYP8NN) return("8NN");
 if(n == PR$_SID_TYPUV1) return("UV1");
 if(n == PR$_SID_TYPUV2) return("UV2");
 if(n == PR$_SID_TYP009) return("009");
 if(n == PR$_SID_TYP650) return("650");
 if(n == PR$_SID_TYP9RR) return("9RR");
 if(n == PR$_SID_TYP8PS) return("8PS");
 return("unknown");}

