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