xref: /titanic_51/usr/src/uts/common/io/etheraddr.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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