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