2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * Function implementations to convert between link layer addresses and
2N/A * ascii representations of the form "x:x:x:...:x:x:x" where x is a hex
2N/A * number between 0x00 and 0xff; the bytes are always in network order.
2N/A */
2N/A
2N/A#include <stdio.h>
2N/A#include <ctype.h>
2N/A#include <stdlib.h>
2N/A#include <sys/types.h>
2N/A#include <net/if_dl.h>
2N/A
2N/A/*
2N/A * Converts a "size" bytes long mac address to its string representation.
2N/A * Currently, the "mactype" is unused, but in the future, the string
2N/A * can be modulated by "mactype" (IFT_* value from <net/if_types.h>)
2N/A */
2N/A/* ARGSUSED */
2N/Achar *
2N/A_link_ntoa(const unsigned char *macaddr, char *str, int size, int mactype)
2N/A{
2N/A char *buf;
2N/A int i, n;
2N/A
2N/A if (((buf = str) == NULL) &&
2N/A ((buf = malloc(3 * size)) == NULL))
2N/A return (NULL);
2N/A n = sprintf(buf, "%x", *macaddr++);
2N/A for (i = 0; i < (size - 1); i++)
2N/A n += sprintf(buf+n, ":%x", *macaddr++);
2N/A return (buf);
2N/A}
2N/A
2N/A/*
2N/A * Converts a string possibly representing a link address into its
2N/A * bit format, returning length of the address in bytes.
2N/A */
2N/Auchar_t *
2N/A_link_aton(const char *ascaddr, int *maclen)
2N/A{
2N/A unsigned char cval, num = 0;
2N/A int idx = 0, numcolons = 0, digits = 0;
2N/A uchar_t *netaddr;
2N/A const char *cptr;
2N/A char lastc = ':';
2N/A
2N/A while (isspace(*ascaddr))
2N/A ascaddr++;
2N/A
2N/A /*
2N/A * Find how many :'s in the string. Also sanity check
2N/A * the string for valid hex chars, absence of white
2N/A * spaces, not starting or ending with :, absence of
2N/A * consecutive :'s, excessive digits per element
2N/A * and non-null string.
2N/A */
2N/A cptr = ascaddr;
2N/A while ((cval = *cptr++) != '\0') {
2N/A if (cval == ':') {
2N/A if (lastc == ':')
2N/A break;
2N/A numcolons++;
2N/A digits = 0;
2N/A } else if (!isxdigit(cval)) {
2N/A break;
2N/A } else {
2N/A digits++;
2N/A }
2N/A
2N/A if (digits > 2)
2N/A break;
2N/A
2N/A lastc = cval;
2N/A }
2N/A if ((lastc == ':') || (cval != '\0' && !isspace(cval)) ||
2N/A (digits > 2)) {
2N/A *maclen = -1;
2N/A return (NULL);
2N/A }
2N/A
2N/A if ((netaddr = malloc(numcolons + 1)) == NULL) {
2N/A *maclen = 0;
2N/A return (NULL);
2N/A }
2N/A
2N/A for (;;) {
2N/A cval = *ascaddr++;
2N/A if (isdigit(cval)) {
2N/A num = (num << 4) | (cval - '0');
2N/A } else if (isxdigit(cval)) {
2N/A num = (num << 4) |
2N/A (cval - (isupper(cval) ? 'A' : 'a') + 10);
2N/A } else if (cval == ':') {
2N/A netaddr[idx++] = num;
2N/A num = 0;
2N/A } else {
2N/A /*
2N/A * We must have hit a whitespace. Stop
2N/A * parsing now.
2N/A */
2N/A netaddr[idx++] = num;
2N/A break;
2N/A }
2N/A }
2N/A *maclen = idx;
2N/A return (netaddr);
2N/A}