Home | History | Annotate | Download | only in io
      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