From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 28-AUG-1990 09:16:29.17
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	HOW TO GET THE: hardware ID on VMS

Received:  by crdgw1.ge.com (5.57/GE 1.70)
	 id AA14683; Mon, 27 Aug 90 23:56:46 EDT
Received: From UCBVAX.BERKELEY.EDU by CRVAX.SRI.COM with TCP; Mon, 27 AUG 90 20:42:27 PDT
Received: by ucbvax.Berkeley.EDU (5.63/1.42)
	id AA28758; Mon, 27 Aug 90 20:38:12 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 27 Aug 90 19:50:26 GMT
From: swrinde!zaphod.mps.ohio-state.edu!samsung!mitech!gjc@ucsd.edu
Organization: Mitech Corporation, Concord MA
Subject: HOW TO GET THE: hardware ID on VMS
Message-Id: <4661@mitech.com>
References: <42A7B31FCBBF2118BD@vms2.uni-c.dk>, <BARKELEW.90Aug27132240@diablo.tsd.arlut.utexas.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

In article <BARKELEW.90Aug27132240@diablo.tsd.arlut.utexas.edu>, barkelew@tsd.arlut.utexas.edu (David Barkelew) writes:
> 
> What you really need is a way for the software to read the Ethernet
> HW address.  "$mcr ncp show known line characteristics" will do the
> job interactively, and I guess could be directed to a file, parsed,
> etc. (KLUDGE!!).  Maybe one of the real VMS wizzards knows how to get
> this info from a HLL? (I'd like to know myself!)
> --

This is pretty cute code actually, and gets the site-id, the date,
and the hardware (ROM) ethernet address. Error checking (system
service status return codes, IOSB, type codes).


/* 
   21-DEC-88 George Carrette, Mitech Corporation, 508-371-2002 (GJC@MITECH.COM)
   74 Junction Square, Concord MA 01742

THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.


 */
 


#include <stdio.h>

char *decode_cpu();

main()
{int retval;
 unsigned char eaddr[6];
 long month,cpu,sn,sid;
 if (get_eaddr_hwa(&eaddr,&month,&cpu,&sn,&sid))
   printf("NET = %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("MTH = %d\n",month);
 printf("SID = %d (%X)\n",sid,sid);
 printf("\n");
 printf("CPU = %d (%s)\n",cpu,decode_cpu(cpu));
 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,month,cpu,sn,sid)
     char *eaddr;long *month,*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;
 struct numtim
   {unsigned short year;
    unsigned short month;
    unsigned short day;
    unsigned short hour;
    unsigned short minute;
    unsigned short second;
    unsigned short cents;} numarg;
 retval = sys$numtim(&numarg,0);
 if (retval == SS$_NORMAL)
   {if (numarg.year < 1988)
      *month = 0;
    else
      *month = (numarg.year - 1988) * 12 + numarg.month;}
 else
   *month = 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");}

