On Fri, 2007-08-17 at 22:36 +0530, Anil Gulecha wrote: > On 8/17/07, Garrett D'Amore <[EMAIL PROTECTED]> wrote: > > Can you figure out a way to use the unique serial number of the CPU? Or > > perhaps the factory MAC address of one of the NICs? > > > > On SPARC, we have hostids that are unique, but unforutnately I don't > > believe that x86 has that ability. > > > > I've considered both of these. > > 1) CPU serial number - x86 cpus do not have unique ids.. sparc does!
* actually most CPUs do have this, though it may be disabled by default in the system BIOS > 2) i considered using the 48bit mac id of the Ethernet card.. however > ifconfig doesn't o/p the details that early in the boot process. If > there another method to get the card detials, I could use it. There is a DLPI method to achieve this. I've attached a C file that can query the MAC address of an ethernet device, even one that isn't plumbed by IP. (You need to know the name of the ethernet device, though.) If you need a routine to query for ethernet devices (walking libdevinfo), let me know. I can probably write without too much difficulty, though there should be code if ifconfig -a plumb or you could use dladm to find one. Anyway, to use my "apmacid" utility, use "apmacid <device>". The code is old code (a utility I wrote for my own testing purposes back in 1999), but it still works. If you want to include it verbatim, I'll probably need to mark it with the CDDL. -- Garrett > > If there isnt one, i'll write a small hashing utility in C and use the > o/p of scanpci. > > Anil
#pragma ident "%W% %E% SMI" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <ctype.h> #include <errno.h> #include <stropts.h> #include <sys/dlpi.h> static int ppa; static char buffer [1024]; void usage() { fprintf(stderr, "usage: apmacid [-acfl] interface ...\n"); exit(1); } int dlpi_open_attach(char *interface, int *ppa) { int index; int fd = -1; dl_attach_req_t *attach_req; dl_ok_ack_t *ok_ack; int flags; struct strbuf ctl; chdir("/dev"); if ((!interface) || !(strlen(interface))) { perror("invalid NULL interface name!\n"); return (-1); } if ((fd = open(interface, O_RDWR)) == -1) { if (errno != ENOENT) { perror(interface); return (-1); } } else { /* no attach required; its style 1 */ return (fd); } /* style 2, determine name and ppa */ for (;;) { index = strcspn(interface, "0123456789"); if (strlen(interface + index) == strspn(interface + index, "0123456789")) { break; } index += strspn(interface + index, "0123456789"); } *ppa = atoi(interface + index); interface[index] = 0; if ((fd = open(interface, O_RDWR)) == -1) { perror(interface); return (-1); } attach_req = (dl_attach_req_t *) buffer; attach_req->dl_primitive = DL_ATTACH_REQ; attach_req->dl_ppa = *ppa; ctl.len = sizeof (dl_attach_req_t); ctl.buf = buffer; if (putmsg(fd, &ctl, NULL, 0) < 0) { perror("apmacid: putmsg"); (void) close(fd); return (-1); } flags = 0; ctl.maxlen = sizeof (buffer); ctl.buf = (void *) buffer; ok_ack = (dl_ok_ack_t *) buffer; /* wait for DL_OK_ACK, if none arrives program will hang */ if (getmsg(fd, &ctl, NULL, &flags) < 0) { perror("apmacid: getmsg"); (void) close(fd); return (-1); } if ((ok_ack->dl_primitive != DL_OK_ACK) || (ok_ack->dl_correct_primitive != DL_ATTACH_REQ)) { switch (ok_ack->dl_primitive) { case DL_OK_ACK: printf ("DL_OK_ACK goodprim %d\n", ok_ack->dl_correct_primitive); break; case DL_ERROR_ACK: { dl_error_ack_t *errack = (dl_error_ack_t *)ok_ack; printf ("DL_ERROR_ACK badprim %d, err %d, unixerr %d\n", errack->dl_error_primitive, errack->dl_errno, errack->dl_unix_errno); break; default: printf("Unxpected primitive %d\n", ok_ack->dl_primitive); break; } } perror("apmacid: dlpi error\n"); (void) close(fd); return (-1); } return (fd); } int dlpi_get_phys_addr(int fd, t_uscalar_t addr_type, char **addr, int *len) { dl_phys_addr_req_t *phys_addr_req; dl_phys_addr_ack_t *phys_addr_ack; struct strbuf ctl; int flags = 0; phys_addr_req = (dl_phys_addr_req_t *) buffer; phys_addr_req->dl_primitive = DL_PHYS_ADDR_REQ; phys_addr_req->dl_addr_type = addr_type; ctl.buf = buffer; ctl.len = sizeof (dl_phys_addr_req_t); if (putmsg(fd, &ctl, NULL, 0) < 0) { perror("putmsg"); return (-1); } ctl.maxlen = sizeof (buffer); ctl.buf = buffer; phys_addr_ack = (dl_phys_addr_ack_t *) buffer; if (getmsg(fd, &ctl, NULL, &flags) < 0) { perror("getmsg"); } if (phys_addr_ack->dl_primitive != DL_PHYS_ADDR_ACK) { perror("DLPI error: expected DL_PHYS_ADDR_ACK"); return (-1); } *len = phys_addr_ack->dl_addr_length; *addr = buffer + phys_addr_ack->dl_addr_offset; return (0); } int dlpi_get_brdcast_addr(int fd, char **addr, int *len) { dl_info_req_t *info_req; dl_info_ack_t *info_ack; struct strbuf ctl; int flags = 0; info_req = (dl_info_req_t *) buffer; info_req->dl_primitive = DL_INFO_REQ; ctl.buf = buffer; ctl.len = sizeof (dl_info_req_t); if (putmsg(fd, &ctl, NULL, 0) < 0) { perror("putmsg"); return (-1); } ctl.maxlen = sizeof (buffer); ctl.buf = buffer; info_ack = (dl_info_ack_t *) buffer; if (getmsg(fd, &ctl, NULL, &flags) < 0) { perror("getmsg"); } if (info_ack->dl_primitive != DL_INFO_ACK) { perror("DLPI error"); return (-1); } *len = info_ack->dl_brdcst_addr_length; *addr = buffer + info_ack->dl_brdcst_addr_offset; return (0); } void printaddr(char *addr, int len) { int idx = 0; while (idx < len) { printf("%x", (unsigned char) addr[idx]); idx++; if (idx < len) { printf(":"); } } printf("\n"); } int main(int argc, char **argv) { int fd; int optc; int num_opts = 0; int do_all = 0; int do_factory = 0; int do_current = 0; int do_local = 0; int do_brdcast = 0; int do_multiple = 0; char *iface = NULL; int ppa; char *addr; int len; while ((optc = getopt(argc, argv, "afclb")) != EOF) { switch (optc) { case 'a': do_all = 1; num_opts += 2; /* enable labelling */ break; case 'f': do_factory = 1; num_opts++; break; case 'c': do_current = 1; num_opts++; break; case 'l': do_local = 1; num_opts++; break; case 'b': do_brdcast = 1; num_opts++; break; case '?': usage(); break; } } /* a reasonable default */ if (!num_opts) { do_current = 1; } if (optind >= argc) { usage(); return (0); } if ((optind + 1) < argc) { /* multiple interfaces */ do_multiple = 1; } while (optind < argc) { iface = argv[optind++]; ppa = -1; if (do_multiple) { printf("%s:%s", iface, num_opts > 1 ? "\n" : " "); } fd = dlpi_open_attach(iface, &ppa); if (fd == -1) { continue; } if (do_all || do_current) { if (dlpi_get_phys_addr(fd, DL_CURR_PHYS_ADDR, &addr, &len)) { (void) close(fd); continue; } if (num_opts > 1) { printf("%scurrent: ", do_multiple ? "\t" : ""); } printaddr(addr, len); } if (do_all || do_factory) { if (dlpi_get_phys_addr(fd, DL_FACT_PHYS_ADDR, &addr, &len)) { (void) close(fd); continue; } if (num_opts > 1) { printf("%sfactory: ", do_multiple ? "\t" : ""); } printaddr(addr, len); } if (do_all || do_local) { if (dlpi_get_phys_addr(fd, DL_FACT_PHYS_ADDR, &addr, &len)) { (void) close(fd); continue; } /* * this rule only works for 6-byte ULAs, taken * from IEEE Std. 802-1990. */ if (len == 6) { addr[2] |= 2; } if (num_opts > 1) { printf("%slocally-administered: ", do_multiple ? "\t" : ""); } printaddr(addr, len); } if (do_all || do_brdcast) { if (dlpi_get_brdcast_addr(fd, &addr, &len)) { (void) close(fd); continue; } if (num_opts > 1) { printf("%sbroadcast: ", do_multiple ? "\t" : ""); } printaddr(addr, len); } close(fd); } return (0); }
_______________________________________________ opensolaris-code mailing list opensolaris-code@opensolaris.org http://mail.opensolaris.org/mailman/listinfo/opensolaris-code