Annotation of src/lib/libc/net/linkaddr.c, Revision 1.10
1.10 ! lukem 1: /* $NetBSD: linkaddr.c,v 1.9 1998/11/13 15:46:55 christos Exp $ */
1.5 cgd 2:
1.1 cgd 3: /*-
1.5 cgd 4: * Copyright (c) 1990, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
1.6 christos 36: #include <sys/cdefs.h>
1.1 cgd 37: #if defined(LIBC_SCCS) && !defined(lint)
1.5 cgd 38: #if 0
39: static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
40: #else
1.10 ! lukem 41: __RCSID("$NetBSD: linkaddr.c,v 1.9 1998/11/13 15:46:55 christos Exp $");
1.5 cgd 42: #endif
1.1 cgd 43: #endif /* LIBC_SCCS and not lint */
44:
45: #include <sys/types.h>
46: #include <sys/socket.h>
47: #include <net/if_dl.h>
1.10 ! lukem 48:
! 49: #include <assert.h>
1.1 cgd 50: #include <string.h>
51:
52: /* States*/
53: #define NAMING 0
54: #define GOTONE 1
55: #define GOTTWO 2
56: #define RESET 3
57: /* Inputs */
58: #define DIGIT (4*0)
59: #define END (4*1)
60: #define DELIM (4*2)
61: #define LETTER (4*3)
62:
63: void
64: link_addr(addr, sdl)
65: register const char *addr;
66: register struct sockaddr_dl *sdl;
67: {
68: register char *cp = sdl->sdl_data;
1.9 christos 69: char *cplim = sdl->sdl_len + (char *)(void *)sdl;
1.6 christos 70: register int byte = 0, state = NAMING;
71: register int newaddr = 0; /* pacify gcc */
1.1 cgd 72:
1.10 ! lukem 73: _DIAGASSERT(addr != NULL);
! 74: _DIAGASSERT(sdl != NULL);
! 75: #ifdef _DIAGNOSTIC
! 76: if (addr == NULL || sdl == NULL)
! 77: return;
! 78: #endif
! 79:
1.8 kleink 80: (void)memset(&sdl->sdl_family, 0, (size_t)sdl->sdl_len - 1);
1.1 cgd 81: sdl->sdl_family = AF_LINK;
82: do {
83: state &= ~LETTER;
84: if ((*addr >= '0') && (*addr <= '9')) {
1.6 christos 85: newaddr = *addr - '0';
1.1 cgd 86: } else if ((*addr >= 'a') && (*addr <= 'f')) {
1.6 christos 87: newaddr = *addr - 'a' + 10;
1.1 cgd 88: } else if ((*addr >= 'A') && (*addr <= 'F')) {
1.6 christos 89: newaddr = *addr - 'A' + 10;
1.1 cgd 90: } else if (*addr == 0) {
91: state |= END;
92: } else if (state == NAMING &&
93: (((*addr >= 'A') && (*addr <= 'Z')) ||
94: ((*addr >= 'a') && (*addr <= 'z'))))
95: state |= LETTER;
96: else
97: state |= DELIM;
98: addr++;
99: switch (state /* | INPUT */) {
100: case NAMING | DIGIT:
101: case NAMING | LETTER:
1.5 cgd 102: *cp++ = addr[-1];
103: continue;
1.1 cgd 104: case NAMING | DELIM:
1.5 cgd 105: state = RESET;
106: sdl->sdl_nlen = cp - sdl->sdl_data;
107: continue;
1.1 cgd 108: case GOTTWO | DIGIT:
1.5 cgd 109: *cp++ = byte;
110: /* FALLTHROUGH */
1.1 cgd 111: case RESET | DIGIT:
1.5 cgd 112: state = GOTONE;
1.6 christos 113: byte = newaddr;
1.5 cgd 114: continue;
1.1 cgd 115: case GOTONE | DIGIT:
1.5 cgd 116: state = GOTTWO;
1.6 christos 117: byte = newaddr + (byte << 4);
1.5 cgd 118: continue;
1.1 cgd 119: default: /* | DELIM */
1.5 cgd 120: state = RESET;
121: *cp++ = byte;
122: byte = 0;
123: continue;
1.1 cgd 124: case GOTONE | END:
125: case GOTTWO | END:
1.5 cgd 126: *cp++ = byte;
127: /* FALLTHROUGH */
1.1 cgd 128: case RESET | END:
129: break;
130: }
131: break;
132: } while (cp < cplim);
133: sdl->sdl_alen = cp - LLADDR(sdl);
1.9 christos 134: newaddr = cp - (char *)(void *)sdl;
1.6 christos 135: if (newaddr > sizeof(*sdl))
136: sdl->sdl_len = newaddr;
1.1 cgd 137: return;
138: }
139:
1.7 mycroft 140: static const char hexlist[16] = "0123456789abcdef";
1.1 cgd 141:
142: char *
143: link_ntoa(sdl)
144: register const struct sockaddr_dl *sdl;
145: {
146: static char obuf[64];
147: register char *out = obuf;
1.9 christos 148: register size_t i;
1.1 cgd 149: register u_char *in = (u_char *)LLADDR(sdl);
1.5 cgd 150: u_char *inlim = in + sdl->sdl_alen;
1.1 cgd 151: int firsttime = 1;
1.10 ! lukem 152:
! 153: _DIAGASSERT(sdl != NULL);
! 154: #ifdef _DIAGNOSTIC
! 155: if (sdl == NULL)
! 156: return (NULL);
! 157: #endif
1.1 cgd 158:
159: if (sdl->sdl_nlen) {
1.8 kleink 160: (void)memcpy(obuf, sdl->sdl_data, (size_t)sdl->sdl_nlen);
1.1 cgd 161: out += sdl->sdl_nlen;
1.5 cgd 162: if (sdl->sdl_alen)
163: *out++ = ':';
1.1 cgd 164: }
165: while (in < inlim) {
1.5 cgd 166: if (firsttime)
167: firsttime = 0;
168: else
169: *out++ = '.';
1.1 cgd 170: i = *in++;
171: if (i > 0xf) {
172: out[1] = hexlist[i & 0xf];
173: i >>= 4;
174: out[0] = hexlist[i];
175: out += 2;
176: } else
177: *out++ = hexlist[i];
178: }
179: *out = 0;
1.5 cgd 180: return (obuf);
1.1 cgd 181: }
CVSweb <webmaster@jp.NetBSD.org>