revert between 56095 -> 55830 in arch
[AROS.git] / workbench / network / stacks / AROSTCP / netlib / linkaddr.c
blob73bdfc495b1181bb8bc670ba4cfe13f315e66cc1
1 /* $Id$
3 * linkaddr.c - link level address parsing
5 * Copyright © 1994 AmiTCP/IP Group,
6 * Network Solutions Development Inc.
7 * All rights reserved.
9 * Copyright © 1991 Regents of the University of California.
12 #if 0
13 static char sccsid[] = "@(#)linkaddr.c 5.2 (Berkeley) 2/24/91";
14 #endif
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <net/if.h>
19 #include <net/if_dl.h>
20 #include <string.h>
22 /* States*/
23 #define NAMING 0
24 #define GOTONE 1
25 #define GOTTWO 2
26 #define RESET 3
27 /* Inputs */
28 #define DIGIT (4*0)
29 #define END (4*1)
30 #define DELIM (4*2)
31 #define LETTER (4*3)
33 void
34 link_addr(addr, sdl)
35 register const char *addr;
36 register struct sockaddr_dl *sdl;
38 register char *cp = sdl->sdl_data;
39 char *cplim = sdl->sdl_len + (char *)sdl;
40 register int byte = 0, state = NAMING, new;
42 bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
43 sdl->sdl_family = AF_LINK;
44 do {
45 state &= ~LETTER;
46 if ((*addr >= '0') && (*addr <= '9')) {
47 new = *addr - '0';
48 } else if ((*addr >= 'a') && (*addr <= 'f')) {
49 new = *addr - 'a' + 10;
50 } else if ((*addr >= 'A') && (*addr <= 'F')) {
51 new = *addr - 'A' + 10;
52 } else if (*addr == 0) {
53 state |= END;
54 } else if (state == NAMING &&
55 (((*addr >= 'A') && (*addr <= 'Z')) ||
56 ((*addr >= 'a') && (*addr <= 'z'))))
57 state |= LETTER;
58 else
59 state |= DELIM;
60 addr++;
61 switch (state /* | INPUT */) {
62 case NAMING | DIGIT:
63 case NAMING | LETTER:
64 *cp++ = addr[-1]; continue;
65 case NAMING | DELIM:
66 state = RESET; sdl->sdl_nlen = cp - sdl->sdl_data; continue;
67 case GOTTWO | DIGIT:
68 *cp++ = byte; /*FALLTHROUGH*/
69 case RESET | DIGIT:
70 state = GOTONE; byte = new; continue;
71 case GOTONE | DIGIT:
72 state = GOTTWO; byte = new + (byte << 4); continue;
73 default: /* | DELIM */
74 state = RESET; *cp++ = byte; byte = 0; continue;
75 case GOTONE | END:
76 case GOTTWO | END:
77 *cp++ = byte; /* FALLTHROUGH */
78 case RESET | END:
79 break;
81 break;
82 } while (cp < cplim);
83 sdl->sdl_alen = cp - LLADDR(sdl);
84 new = cp - (char *)sdl;
85 if (new > sizeof(*sdl))
86 sdl->sdl_len = new;
87 return;