|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)linkaddr.c 5.1 (Berkeley) 6/1/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: #include <sys/types.h>
25: #include <sys/socket.h>
26: #include <net/if_dl.h>
27:
28: /* States*/
29: #define NAMING 0
30: #define GOTONE 1
31: #define GOTTWO 2
32: #define RESET 3
33: /* Inputs */
34: #define DIGIT (4*0)
35: #define END (4*1)
36: #define DELIM (4*2)
37: #define LETTER (4*3)
38:
39: link_addr(addr, sdl)
40: register char *addr;
41: register struct sockaddr_dl *sdl;
42: {
43: register char *cp = sdl->sdl_data;
44: char *cplim = sdl->sdl_len + (char *)sdl;
45: register int byte = 0, state = NAMING, new;
46:
47: bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
48: sdl->sdl_family = AF_LINK;
49: do {
50: state &= ~LETTER;
51: if ((*addr >= '0') && (*addr <= '9')) {
52: new = *addr - '0';
53: } else if ((*addr >= 'a') && (*addr <= 'f')) {
54: new = *addr - 'a' + 10;
55: } else if ((*addr >= 'A') && (*addr <= 'F')) {
56: new = *addr - 'A' + 10;
57: } else if (*addr == 0) {
58: state |= END;
59: } else if (state == NAMING &&
60: (((*addr >= 'A') && (*addr <= 'Z')) ||
61: ((*addr >= 'a') && (*addr <= 'z'))))
62: state |= LETTER;
63: else
64: state |= DELIM;
65: addr++;
66: switch (state /* | INPUT */) {
67: case NAMING | DIGIT:
68: case NAMING | LETTER:
69: *cp++ = addr[-1]; continue;
70: case NAMING | DELIM:
71: state = RESET; sdl->sdl_nlen = cp - sdl->sdl_data; continue;
72: case GOTTWO | DIGIT:
73: *cp++ = byte; /*FALLTHROUGH*/
74: case RESET | DIGIT:
75: state = GOTONE; byte = new; continue;
76: case GOTONE | DIGIT:
77: state = GOTTWO; byte = new + (byte << 4); continue;
78: default: /* | DELIM */
79: state = RESET; *cp++ = byte; byte = 0; continue;
80: case GOTONE | END:
81: case GOTTWO | END:
82: *cp++ = byte; /* FALLTHROUGH */
83: case RESET | END:
84: break;
85: }
86: break;
87: } while (cp < cplim);
88: sdl->sdl_alen = cp - LLADDR(sdl);
89: new = cp - (char *)sdl;
90: if (new > sizeof(*sdl))
91: sdl->sdl_len = new;
92: return;
93: }
94:
95: static char hexlist[] = "0123456789abcdef";
96:
97: char *
98: link_ntoa(sdl)
99: register struct sockaddr_dl *sdl;
100: {
101: static char obuf[64];
102: register char *out = obuf;
103: register int i;
104: register u_char *in = (u_char *)LLADDR(sdl);
105: u_char *inlim = in + sdl->sdl_nlen;
106: int firsttime = 1;
107:
108: if (sdl->sdl_nlen) {
109: bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
110: out += sdl->sdl_nlen;
111: *out++ = ':';
112: }
113: while (in < inlim) {
114: if (firsttime) firsttime = 0; else *out++ = '.';
115: i = *in++;
116: if (i > 0xf) {
117: out[1] = hexlist[i & 0xf];
118: i >>= 4;
119: out[0] = hexlist[i];
120: out += 2;
121: } else
122: *out++ = hexlist[i];
123: }
124: *out = 0;
125: return(obuf);
126: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.