142710Sbostic /*- 2*61151Sbostic * Copyright (c) 1990, 1993 3*61151Sbostic * The Regents of the University of California. All rights reserved. 442710Sbostic * 542710Sbostic * %sccs.include.redist.c% 642710Sbostic */ 742710Sbostic 842710Sbostic #if defined(LIBC_SCCS) && !defined(lint) 9*61151Sbostic static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 06/04/93"; 1042710Sbostic #endif /* LIBC_SCCS and not lint */ 1142710Sbostic 1242710Sbostic #include <sys/types.h> 1342710Sbostic #include <sys/socket.h> 1442710Sbostic #include <net/if_dl.h> 1546604Sbostic #include <string.h> 1642710Sbostic 1742710Sbostic /* States*/ 1842710Sbostic #define NAMING 0 1942710Sbostic #define GOTONE 1 2042710Sbostic #define GOTTWO 2 2142710Sbostic #define RESET 3 2242710Sbostic /* Inputs */ 2342710Sbostic #define DIGIT (4*0) 2442710Sbostic #define END (4*1) 2542710Sbostic #define DELIM (4*2) 2642710Sbostic #define LETTER (4*3) 2742710Sbostic 2846604Sbostic void link_addr(addr,sdl)2942710Sbosticlink_addr(addr, sdl) 3046604Sbostic register const char *addr; 3146604Sbostic register struct sockaddr_dl *sdl; 3242710Sbostic { 3342710Sbostic register char *cp = sdl->sdl_data; 3442710Sbostic char *cplim = sdl->sdl_len + (char *)sdl; 3542710Sbostic register int byte = 0, state = NAMING, new; 3642710Sbostic 3742710Sbostic bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); 3842710Sbostic sdl->sdl_family = AF_LINK; 3942710Sbostic do { 4042710Sbostic state &= ~LETTER; 4142710Sbostic if ((*addr >= '0') && (*addr <= '9')) { 4242710Sbostic new = *addr - '0'; 4342710Sbostic } else if ((*addr >= 'a') && (*addr <= 'f')) { 4442710Sbostic new = *addr - 'a' + 10; 4542710Sbostic } else if ((*addr >= 'A') && (*addr <= 'F')) { 4642710Sbostic new = *addr - 'A' + 10; 4742710Sbostic } else if (*addr == 0) { 4842710Sbostic state |= END; 4942710Sbostic } else if (state == NAMING && 5042710Sbostic (((*addr >= 'A') && (*addr <= 'Z')) || 5142710Sbostic ((*addr >= 'a') && (*addr <= 'z')))) 5242710Sbostic state |= LETTER; 5342710Sbostic else 5442710Sbostic state |= DELIM; 5542710Sbostic addr++; 5642710Sbostic switch (state /* | INPUT */) { 5742710Sbostic case NAMING | DIGIT: 5842710Sbostic case NAMING | LETTER: 5954416Sbostic *cp++ = addr[-1]; 6054416Sbostic continue; 6142710Sbostic case NAMING | DELIM: 6254416Sbostic state = RESET; 6354416Sbostic sdl->sdl_nlen = cp - sdl->sdl_data; 6454416Sbostic continue; 6542710Sbostic case GOTTWO | DIGIT: 6654416Sbostic *cp++ = byte; 6754416Sbostic /* FALLTHROUGH */ 6842710Sbostic case RESET | DIGIT: 6954416Sbostic state = GOTONE; 7054416Sbostic byte = new; 7154416Sbostic continue; 7242710Sbostic case GOTONE | DIGIT: 7354416Sbostic state = GOTTWO; 7454416Sbostic byte = new + (byte << 4); 7554416Sbostic continue; 7642710Sbostic default: /* | DELIM */ 7754416Sbostic state = RESET; 7854416Sbostic *cp++ = byte; 7954416Sbostic byte = 0; 8054416Sbostic continue; 8142710Sbostic case GOTONE | END: 8242710Sbostic case GOTTWO | END: 8354416Sbostic *cp++ = byte; 8454416Sbostic /* FALLTHROUGH */ 8542710Sbostic case RESET | END: 8642710Sbostic break; 8742710Sbostic } 8842710Sbostic break; 8942710Sbostic } while (cp < cplim); 9042710Sbostic sdl->sdl_alen = cp - LLADDR(sdl); 9142710Sbostic new = cp - (char *)sdl; 9242710Sbostic if (new > sizeof(*sdl)) 9342710Sbostic sdl->sdl_len = new; 9442710Sbostic return; 9542710Sbostic } 9642710Sbostic 9742710Sbostic static char hexlist[] = "0123456789abcdef"; 9842710Sbostic 9942710Sbostic char * link_ntoa(sdl)10042710Sbosticlink_ntoa(sdl) 10146604Sbostic register const struct sockaddr_dl *sdl; 10242710Sbostic { 10342710Sbostic static char obuf[64]; 10442710Sbostic register char *out = obuf; 10542710Sbostic register int i; 10642710Sbostic register u_char *in = (u_char *)LLADDR(sdl); 10750669Skarels u_char *inlim = in + sdl->sdl_alen; 10842710Sbostic int firsttime = 1; 10942710Sbostic 11042710Sbostic if (sdl->sdl_nlen) { 11142710Sbostic bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen); 11242710Sbostic out += sdl->sdl_nlen; 11350669Skarels if (sdl->sdl_alen) 11450669Skarels *out++ = ':'; 11542710Sbostic } 11642710Sbostic while (in < inlim) { 11750669Skarels if (firsttime) 11850669Skarels firsttime = 0; 11950669Skarels else 12050669Skarels *out++ = '.'; 12142710Sbostic i = *in++; 12242710Sbostic if (i > 0xf) { 12342710Sbostic out[1] = hexlist[i & 0xf]; 12442710Sbostic i >>= 4; 12542710Sbostic out[0] = hexlist[i]; 12642710Sbostic out += 2; 12742710Sbostic } else 12842710Sbostic *out++ = hexlist[i]; 12942710Sbostic } 13042710Sbostic *out = 0; 13150669Skarels return (obuf); 13242710Sbostic } 133