141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak/*
241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * Copyright (C) 2010 The Android Open Source Project
341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * All rights reserved.
441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *
541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * Redistribution and use in source and binary forms, with or without
641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * modification, are permitted provided that the following conditions
741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * are met:
841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *  * Redistributions of source code must retain the above copyright
941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *    notice, this list of conditions and the following disclaimer.
1041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *  * Redistributions in binary form must reproduce the above copyright
1141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *    notice, this list of conditions and the following disclaimer in
1241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *    the documentation and/or other materials provided with the
1341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *    distribution.
1441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak *
1541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * SUCH DAMAGE.
2741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak */
2841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
2941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak#include <stdio.h>
3041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak#include <stdlib.h>
3141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak#include <sys/types.h>
3241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak#include <net/if_ether.h>
3341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak#include <ctype.h>
3441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
3541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczakstatic inline int
3641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczakxdigit (char c) {
3741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    unsigned d;
3841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    d = (unsigned)(c-'0');
3941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    if (d < 10) return (int)d;
4041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    d = (unsigned)(c-'a');
4141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    if (d < 6) return (int)(10+d);
4241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    d = (unsigned)(c-'A');
4341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    if (d < 6) return (int)(10+d);
4441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    return -1;
4541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak}
4641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
4741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak/*
4841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * Convert Ethernet address in the standard hex-digits-and-colons to binary
4941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * representation.
5041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * Re-entrant version (GNU extensions)
5141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak */
5241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczakstruct ether_addr *
5341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczakether_aton_r (const char *asc, struct ether_addr * addr)
5441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak{
5541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    int i, val0, val1;
5641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    for (i = 0; i < ETHER_ADDR_LEN; ++i) {
5741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        val0 = xdigit(*asc);
5841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        asc++;
5941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        if (val0 < 0)
6041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak            return NULL;
6141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
6241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        val1 = xdigit(*asc);
6341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        asc++;
6441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        if (val1 < 0)
6541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak            return NULL;
6641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
6741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        addr->ether_addr_octet[i] = (u_int8_t)((val0 << 4) + val1);
6841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
6941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        if (i < ETHER_ADDR_LEN - 1) {
7041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak            if (*asc != ':')
7141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak                return NULL;
7241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak            asc++;
7341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        }
7441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    }
7541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    if (*asc != '\0')
7641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak        return NULL;
7741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    return addr;
7841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak}
7941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak
8041e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak/*
8141e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * Convert Ethernet address in the standard hex-digits-and-colons to binary
8241e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak * representation.
8341e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak */
8441e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczakstruct ether_addr *
8541e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczakether_aton (const char *asc)
8641e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak{
8741e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    static struct ether_addr addr;
8841e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak    return ether_aton_r(asc, &addr);
8941e533af4a2720c1dc228ba40b6582ca53085c3aSzymon Jakubczak}
90