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 #include <sys/types.h> 22 #include <sys/sysmacros.h> 23 #include <sys/ethernet.h> 24 #include <sys/cmn_err.h> 25 #include <sys/ksynch.h> 26 27 /* 28 * Store and retrieve local individual ethernet address. 29 * This is typically initialized (called with 'hint' nonnull) 30 * by the boot code. 31 */ 32 33 static kmutex_t localetheraddr_lock; /* Perimeter lock for localetheraddr */ 34 35 int 36 localetheraddr(struct ether_addr *hint, struct ether_addr *result) 37 { 38 static int found = 0; 39 static struct ether_addr addr; 40 41 mutex_enter(&localetheraddr_lock); 42 if (!found) { 43 if (hint == NULL) { 44 mutex_exit(&localetheraddr_lock); 45 return (0); 46 } 47 found = 1; 48 addr = *hint; 49 cmn_err(CE_CONT, "?Ethernet address = %s\n", 50 ether_sprintf(&addr)); 51 } 52 if (result != NULL) 53 *result = addr; 54 mutex_exit(&localetheraddr_lock); 55 return (1); 56 } 57 58 /* 59 * Convert Ethernet address to printable (loggable) representation. 60 * 61 * XXX This is not MT-safe, but its only race is for the "etherbuf". 62 */ 63 char * 64 ether_sprintf(struct ether_addr *addr) 65 { 66 static char etherbuf[18]; 67 68 (void) snprintf(etherbuf, sizeof (etherbuf), "%x:%x:%x:%x:%x:%x", 69 addr->ether_addr_octet[0], addr->ether_addr_octet[1], 70 addr->ether_addr_octet[2], addr->ether_addr_octet[3], 71 addr->ether_addr_octet[4], addr->ether_addr_octet[5]); 72 return (etherbuf); 73 } 74 75 static int 76 hexval(char dig) 77 { 78 if ('0' <= dig && dig <= '9') { 79 return (dig - '0'); 80 } else if ('a' <= dig && dig <= 'f') { 81 return (dig - 'a' + 10); 82 } else if ('A' <= dig && dig <= 'F') { 83 return (dig - 'A' + 10); 84 } else { 85 return (-1); 86 } 87 } 88 89 /* 90 * Convert Ethernet address from ascii to binary form. 91 * Return number of bytes written. 92 */ 93 int 94 ether_aton(char *addr, uchar_t *macaddr) 95 { 96 int i = 0; 97 uint_t val = 0; 98 char *cp = addr; 99 100 while (*cp != 0 && i < 6) { 101 if (*cp == ':') { 102 macaddr[i++] = val; 103 val = 0; 104 cp++; 105 continue; 106 } 107 108 val = (val << 4) | hexval(*cp++); 109 } 110 macaddr[i] = val; 111 return (i + 1); 112 } 113