1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 7*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate /* 10*7c478bd9Sstevel@tonic-gate * Copyright (c) 1982, 1986 Regents of the University of California. 11*7c478bd9Sstevel@tonic-gate * All rights reserved. 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 14*7c478bd9Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given 15*7c478bd9Sstevel@tonic-gate * to the University of California at Berkeley. The name of the University 16*7c478bd9Sstevel@tonic-gate * may not be used to endorse or promote products derived from this 17*7c478bd9Sstevel@tonic-gate * software without specific prior written permission. This software 18*7c478bd9Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty. 19*7c478bd9Sstevel@tonic-gate */ 20*7c478bd9Sstevel@tonic-gate 21*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 22*7c478bd9Sstevel@tonic-gate 23*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 24*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 25*7c478bd9Sstevel@tonic-gate #include <sys/ethernet.h> 26*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 27*7c478bd9Sstevel@tonic-gate #include <sys/ksynch.h> 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Store and retrieve local individual ethernet address. 31*7c478bd9Sstevel@tonic-gate * This is typically initialized (called with 'hint' nonnull) 32*7c478bd9Sstevel@tonic-gate * by the boot code. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate static kmutex_t localetheraddr_lock; /* Perimeter lock for localetheraddr */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate int 38*7c478bd9Sstevel@tonic-gate localetheraddr(struct ether_addr *hint, struct ether_addr *result) 39*7c478bd9Sstevel@tonic-gate { 40*7c478bd9Sstevel@tonic-gate static int found = 0; 41*7c478bd9Sstevel@tonic-gate static struct ether_addr addr; 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate mutex_enter(&localetheraddr_lock); 44*7c478bd9Sstevel@tonic-gate if (!found) { 45*7c478bd9Sstevel@tonic-gate if (hint == NULL) { 46*7c478bd9Sstevel@tonic-gate mutex_exit(&localetheraddr_lock); 47*7c478bd9Sstevel@tonic-gate return (0); 48*7c478bd9Sstevel@tonic-gate } 49*7c478bd9Sstevel@tonic-gate found = 1; 50*7c478bd9Sstevel@tonic-gate addr = *hint; 51*7c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "?Ethernet address = %s\n", 52*7c478bd9Sstevel@tonic-gate ether_sprintf(&addr)); 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate if (result != NULL) 55*7c478bd9Sstevel@tonic-gate *result = addr; 56*7c478bd9Sstevel@tonic-gate mutex_exit(&localetheraddr_lock); 57*7c478bd9Sstevel@tonic-gate return (1); 58*7c478bd9Sstevel@tonic-gate } 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* 61*7c478bd9Sstevel@tonic-gate * Convert Ethernet address to printable (loggable) representation. 62*7c478bd9Sstevel@tonic-gate * 63*7c478bd9Sstevel@tonic-gate * XXX This is not MT-safe, but its only race is for the "etherbuf". 64*7c478bd9Sstevel@tonic-gate */ 65*7c478bd9Sstevel@tonic-gate char * 66*7c478bd9Sstevel@tonic-gate ether_sprintf(struct ether_addr *addr) 67*7c478bd9Sstevel@tonic-gate { 68*7c478bd9Sstevel@tonic-gate static char etherbuf[18]; 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate (void) snprintf(etherbuf, sizeof (etherbuf), "%x:%x:%x:%x:%x:%x", 71*7c478bd9Sstevel@tonic-gate addr->ether_addr_octet[0], addr->ether_addr_octet[1], 72*7c478bd9Sstevel@tonic-gate addr->ether_addr_octet[2], addr->ether_addr_octet[3], 73*7c478bd9Sstevel@tonic-gate addr->ether_addr_octet[4], addr->ether_addr_octet[5]); 74*7c478bd9Sstevel@tonic-gate return (etherbuf); 75*7c478bd9Sstevel@tonic-gate } 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate static int 78*7c478bd9Sstevel@tonic-gate hexval(char dig) 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate if ('0' <= dig && dig <= '9') { 81*7c478bd9Sstevel@tonic-gate return (dig - '0'); 82*7c478bd9Sstevel@tonic-gate } else if ('a' <= dig && dig <= 'f') { 83*7c478bd9Sstevel@tonic-gate return (dig - 'a' + 10); 84*7c478bd9Sstevel@tonic-gate } else if ('A' <= dig && dig <= 'F') { 85*7c478bd9Sstevel@tonic-gate return (dig - 'A' + 10); 86*7c478bd9Sstevel@tonic-gate } else { 87*7c478bd9Sstevel@tonic-gate return (-1); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate /* 92*7c478bd9Sstevel@tonic-gate * Convert Ethernet address from ascii to binary form. 93*7c478bd9Sstevel@tonic-gate * Return number of bytes written. 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate int 96*7c478bd9Sstevel@tonic-gate ether_aton(char *addr, uchar_t *macaddr) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate int i = 0; 99*7c478bd9Sstevel@tonic-gate uint_t val = 0; 100*7c478bd9Sstevel@tonic-gate char *cp = addr; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate while (*cp != 0 && i < 6) { 103*7c478bd9Sstevel@tonic-gate if (*cp == ':') { 104*7c478bd9Sstevel@tonic-gate macaddr[i++] = val; 105*7c478bd9Sstevel@tonic-gate val = 0; 106*7c478bd9Sstevel@tonic-gate cp++; 107*7c478bd9Sstevel@tonic-gate continue; 108*7c478bd9Sstevel@tonic-gate } 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate val = (val << 4) | hexval(*cp++); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate macaddr[i] = val; 113*7c478bd9Sstevel@tonic-gate return (i + 1); 114*7c478bd9Sstevel@tonic-gate } 115