1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/*- 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Copyright (c) 1990, 1993 3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * The Regents of the University of California. All rights reserved. 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met: 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer. 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer in the 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * documentation and/or other materials provided with the distribution. 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 3. Neither the name of the University nor the names of its contributors 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * may be used to endorse or promote products derived from this software 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * without specific prior written permission. 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE. 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/cdefs.h> 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#if defined(LIBC_SCCS) && !defined(lint) 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93"; 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#endif /* LIBC_SCCS and not lint */ 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/types.h> 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <sys/socket.h> 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <net/if_dl.h> 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h> 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* States*/ 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define NAMING 0 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define GOTONE 1 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define GOTTWO 2 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define RESET 3 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* Inputs */ 47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define DIGIT (4*0) 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define END (4*1) 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define DELIM (4*2) 50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define LETTER (4*3) 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid 53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtlink_addr(addr, sdl) 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const char *addr; 55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct sockaddr_dl *sdl; 56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *cp = sdl->sdl_data; 58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt char *cplim = sdl->sdl_len + (char *)(void *)sdl; 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int byte = 0, state = NAMING; 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int newaddr = 0; 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (void)memset(&sdl->sdl_family, 0, (size_t)sdl->sdl_len - 1); 63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sdl->sdl_family = AF_LINK; 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt do { 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state &= ~LETTER; 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((*addr >= '0') && (*addr <= '9')) { 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newaddr = *addr - '0'; 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if ((*addr >= 'a') && (*addr <= 'f')) { 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newaddr = *addr - 'a' + 10; 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if ((*addr >= 'A') && (*addr <= 'F')) { 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newaddr = *addr - 'A' + 10; 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if (*addr == 0) { 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state |= END; 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if (state == NAMING && 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (((*addr >= 'A') && (*addr <= 'Z')) || 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ((*addr >= 'a') && (*addr <= 'z')))) 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state |= LETTER; 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state |= DELIM; 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr++; 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt switch (state /* | INPUT */) { 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case NAMING | DIGIT: 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case NAMING | LETTER: 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *cp++ = addr[-1]; 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case NAMING | DELIM: 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state = RESET; 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sdl->sdl_nlen = cp - sdl->sdl_data; 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case GOTTWO | DIGIT: 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *cp++ = byte; 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* FALLTHROUGH */ 93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RESET | DIGIT: 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state = GOTONE; 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt byte = newaddr; 96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case GOTONE | DIGIT: 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state = GOTTWO; 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt byte = newaddr + (byte << 4); 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt default: /* | DELIM */ 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state = RESET; 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *cp++ = byte; 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt byte = 0; 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case GOTONE | END: 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case GOTTWO | END: 108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *cp++ = byte; 109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* FALLTHROUGH */ 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt case RESET | END: 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt break; 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } while (cp < cplim); 115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sdl->sdl_alen = cp - LLADDR(sdl); 116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt newaddr = cp - (char *)(void *)sdl; 117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((size_t) newaddr > sizeof(*sdl)) 118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt sdl->sdl_len = newaddr; 119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 121