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