/* get idprom info via openprom interface - mch@squirrel.com 
 *   placed in the public domain by the author - 1 July 1994
 * N.B. the idprom info is actually in NVRAM, so the name is misleading
 *
 * define SOLARIS2 if you are compiling for SOLARIS2 
 * define TEST to include the very simple test driver
 * define DEBUG to produce copious output - including the complete idprom
 *    contents according to openprom 
 *
 * Of course, you need read permission to /dev/openprom to do this. It
 * appears that the default configuration on Solaris 1.x gives everyone
 * read permission, but on Solaris 2.3 you need to be root or in group 
 * sys.
 */

#include <fcntl.h>
#include <sys/types.h>

#if defined(TEST) || defined(DEBUG)
#include <stdio.h>
#endif

#ifdef SOLARIS2
#include <sys/openpromio.h>
#define bzero(a,b) memset((a),0,(b))
#else
#include <sundev/openpromio.h>
#endif


/* 
 * getobphostid - gets hostid according to the openprom driver
 * returns 0 on failure 
 */
unsigned int getobphostid()
{
    struct opio {
       unsigned int size;
       unsigned char arr[OPROMMAXPARAM];
    } foo;
    int fd,done = 0;
#ifdef DEBUG
    int i;
#endif
    if ((fd = open("/dev/openprom", O_RDONLY)) < 0) {
#ifdef DEBUG
        perror("cannot open /dev/openprom");
#endif
        return (0);
    }
    foo.size =  OPROMMAXPARAM;
    bzero(&foo.arr[0],OPROMMAXPARAM);
    if (ioctl(fd, OPROMNEXT, &foo) < 0) {
#ifdef DEBUG
        perror("ioctl failed (OPROMNEXT)");
#endif
        return(0);
    }
    foo.size =  OPROMMAXPARAM;
    bzero(&foo.arr[0],OPROMMAXPARAM);
    for (;!done;) {
        foo.size =  OPROMMAXPARAM;
        if (ioctl(fd, OPROMNXTPROP, &foo) < 0) {
#ifdef DEBUG
            perror("ioctl failed (OPROMNXTPROP)");
#endif
            return(0);
        }
        if (foo.size == 0)   /* not on list ! */
            return 0;
        if (strncmp(&foo.arr[0], "idprom", 6)) 
            continue;
#ifdef DEBUG
        printf("%s: ", &foo.arr[0]);
#endif
        strcpy(&foo.arr[0],&foo.arr[0]);
        foo.size=OPROMMAXPARAM;
        if (ioctl(fd, OPROMGETPROP, &foo) < 0) {
#ifdef DEBUG
            perror("ioctl failed (OPROMGETPROP)");
#endif
            return(0);
        }
#ifdef DEBUG
        for (i=0;i<foo.size;i++) {
            if (!(i%8))
                printf("\n");
            printf("%02x ",foo.arr[i] & 0xff);
        }
        printf("\n");
        printf("hostid = %02x%02x%02x%02x\n", foo.arr[1], foo.arr[12],
            foo.arr[13], foo.arr[14]);
        printf("enet   = %02x:%02x:%02x:%02x:%02x:%02x\n", foo.arr[2],
            foo.arr[3],foo.arr[4],foo.arr[5],foo.arr[6],foo.arr[7]);
#endif
        done=1;
    }   
    close(fd);
    return ((foo.arr[1] << 24)|(foo.arr[12] << 16)|(foo.arr[13] << 8)
            |(foo.arr[14]));
}
#ifdef TEST

main()
{
    printf("%08x\n", getobphostid());
	return(0);
}
#endif
