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
localetheraddr(struct ether_addr * hint,struct ether_addr * result)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 *
ether_sprintf(struct ether_addr * addr)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
hexval(char dig)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
ether_aton(char * addr,uchar_t * macaddr)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