Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/net/eui64.c
39476 views
1
/*
2
* Copyright 2004 The Aerospace Corporation. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions, and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions, and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. The name of The Aerospace Corporation may not be used to endorse or
14
* promote products derived from this software.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*
28
* Copyright (c) 1995
29
* Bill Paul <[email protected]>. All rights reserved.
30
*
31
* Redistribution and use in source and binary forms, with or without
32
* modification, are permitted provided that the following conditions
33
* are met:
34
* 1. Redistributions of source code must retain the above copyright
35
* notice, this list of conditions and the following disclaimer.
36
* 2. Redistributions in binary form must reproduce the above copyright
37
* notice, this list of conditions and the following disclaimer in the
38
* documentation and/or other materials provided with the distribution.
39
* 3. All advertising materials mentioning features or use of this software
40
* must display the following acknowledgement:
41
* This product includes software developed by Bill Paul.
42
* 4. Neither the name of the author nor the names of any co-contributors
43
* may be used to endorse or promote products derived from this software
44
* without specific prior written permission.
45
*
46
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
47
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56
* SUCH DAMAGE.
57
*
58
* EUI-64 conversion and lookup routines
59
*
60
*
61
* Converted from ether_addr.c rev
62
* FreeBSD: src/lib/libc/net/eui64.c,v 1.15 2002/04/08 07:51:10 ru Exp
63
* by Brooks Davis
64
*
65
* Written by Bill Paul <[email protected]>
66
* Center for Telecommunications Research
67
* Columbia University, New York City
68
*/
69
70
#include <stdio.h>
71
#include <paths.h>
72
#include <sys/param.h>
73
#include <sys/eui64.h>
74
#include <string.h>
75
#include <stdlib.h>
76
#ifdef YP
77
#include <rpc/rpc.h>
78
#include <rpcsvc/yp_prot.h>
79
#include <rpcsvc/ypclnt.h>
80
#endif
81
82
#ifndef _PATH_EUI64
83
#define _PATH_EUI64 "/etc/eui64"
84
#endif
85
86
static int eui64_line(const char *l, struct eui64 *e, char *hostname,
87
size_t len);
88
89
/*
90
* Parse a string of text containing an EUI-64 and hostname
91
* and separate it into its component parts.
92
*/
93
static int
94
eui64_line(const char *l, struct eui64 *e, char *hostname, size_t len)
95
{
96
char *line, *linehead, *cur;
97
98
linehead = strdup(l);
99
if (linehead == NULL)
100
return (-1);
101
line = linehead;
102
103
/* Find and parse the EUI64 */
104
while ((cur = strsep(&line, " \t\r\n")) != NULL) {
105
if (*cur != '\0') {
106
if (eui64_aton(cur, e) == 0)
107
break;
108
else
109
goto bad;
110
}
111
}
112
113
/* Find the hostname */
114
while ((cur = strsep(&line, " \t\r\n")) != NULL) {
115
if (*cur != '\0') {
116
if (strlcpy(hostname, cur, len) <= len)
117
break;
118
else
119
goto bad;
120
}
121
}
122
123
/* Make sure what remains is either whitespace or a comment */
124
while ((cur = strsep(&line, " \t\r\n")) != NULL) {
125
if (*cur == '#')
126
break;
127
if (*cur != '\0')
128
goto bad;
129
}
130
131
free(linehead);
132
return (0);
133
134
bad:
135
free(linehead);
136
return (-1);
137
}
138
139
/*
140
* Convert an ASCII representation of an EUI-64 to binary form.
141
*/
142
int
143
eui64_aton(const char *a, struct eui64 *e)
144
{
145
int i;
146
unsigned int o0, o1, o2, o3, o4, o5, o6, o7;
147
148
/* canonical form */
149
i = sscanf(a, "%x-%x-%x-%x-%x-%x-%x-%x",
150
&o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
151
if (i == EUI64_LEN)
152
goto good;
153
/* ethernet form */
154
i = sscanf(a, "%x:%x:%x:%x:%x:%x:%x:%x",
155
&o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
156
if (i == EUI64_LEN)
157
goto good;
158
/* classic fwcontrol/dconschat form */
159
i = sscanf(a, "0x%2x%2x%2x%2x%2x%2x%2x%2x",
160
&o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
161
if (i == EUI64_LEN)
162
goto good;
163
/* MAC format (-) */
164
i = sscanf(a, "%x-%x-%x-%x-%x-%x",
165
&o0, &o1, &o2, &o5, &o6, &o7);
166
if (i == 6) {
167
o3 = 0xff;
168
o4 = 0xfe;
169
goto good;
170
}
171
/* MAC format (:) */
172
i = sscanf(a, "%x:%x:%x:%x:%x:%x",
173
&o0, &o1, &o2, &o5, &o6, &o7);
174
if (i == 6) {
175
o3 = 0xff;
176
o4 = 0xfe;
177
goto good;
178
}
179
180
return (-1);
181
182
good:
183
e->octet[0]=o0;
184
e->octet[1]=o1;
185
e->octet[2]=o2;
186
e->octet[3]=o3;
187
e->octet[4]=o4;
188
e->octet[5]=o5;
189
e->octet[6]=o6;
190
e->octet[7]=o7;
191
192
return (0);
193
}
194
195
/*
196
* Convert a binary representation of an EUI-64 to an ASCII string.
197
*/
198
int
199
eui64_ntoa(const struct eui64 *id, char *a, size_t len)
200
{
201
int i;
202
203
i = snprintf(a, len, "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
204
id->octet[0], id->octet[1], id->octet[2], id->octet[3],
205
id->octet[4], id->octet[5], id->octet[6], id->octet[7]);
206
if (i < 23 || i >= len)
207
return (-1);
208
return (0);
209
}
210
211
/*
212
* Map an EUI-64 to a hostname. Use either /etc/eui64 or NIS/YP.
213
*/
214
int
215
eui64_ntohost(char *hostname, size_t len, const struct eui64 *id)
216
{
217
FILE *fp;
218
char buf[BUFSIZ + 2];
219
struct eui64 local_eui64;
220
char local_host[MAXHOSTNAMELEN];
221
#ifdef YP
222
char *result;
223
int resultlen;
224
char eui64_a[24];
225
char *yp_domain;
226
#endif
227
if ((fp = fopen(_PATH_EUI64, "re")) == NULL)
228
return (1);
229
230
while (fgets(buf,BUFSIZ,fp)) {
231
if (buf[0] == '#')
232
continue;
233
#ifdef YP
234
if (buf[0] == '+') {
235
if (yp_get_default_domain(&yp_domain))
236
continue;
237
eui64_ntoa(id, eui64_a, sizeof(eui64_a));
238
if (yp_match(yp_domain, "eui64.byid", eui64_a,
239
strlen(eui64_a), &result, &resultlen)) {
240
continue;
241
}
242
strncpy(buf, result, resultlen);
243
buf[resultlen] = '\0';
244
free(result);
245
}
246
#endif
247
if (eui64_line(buf, &local_eui64, local_host,
248
sizeof(local_host)) == 0) {
249
if (bcmp(&local_eui64.octet[0],
250
&id->octet[0], EUI64_LEN) == 0) {
251
/* We have a match */
252
strcpy(hostname, local_host);
253
fclose(fp);
254
return(0);
255
}
256
}
257
}
258
fclose(fp);
259
return (1);
260
}
261
262
/*
263
* Map a hostname to an EUI-64 using /etc/eui64 or NIS/YP.
264
*/
265
int
266
eui64_hostton(const char *hostname, struct eui64 *id)
267
{
268
FILE *fp;
269
char buf[BUFSIZ + 2];
270
struct eui64 local_eui64;
271
char local_host[MAXHOSTNAMELEN];
272
#ifdef YP
273
char *result;
274
int resultlen;
275
char *yp_domain;
276
#endif
277
if ((fp = fopen(_PATH_EUI64, "re")) == NULL)
278
return (1);
279
280
while (fgets(buf,BUFSIZ,fp)) {
281
if (buf[0] == '#')
282
continue;
283
#ifdef YP
284
if (buf[0] == '+') {
285
if (yp_get_default_domain(&yp_domain))
286
continue;
287
if (yp_match(yp_domain, "eui64.byname", hostname,
288
strlen(hostname), &result, &resultlen)) {
289
continue;
290
}
291
strncpy(buf, result, resultlen);
292
buf[resultlen] = '\0';
293
free(result);
294
}
295
#endif
296
if (eui64_line(buf, &local_eui64, local_host,
297
sizeof(local_host)) == 0) {
298
if (strcmp(hostname, local_host) == 0) {
299
/* We have a match */
300
bcopy(&local_eui64, id, sizeof(struct eui64));
301
fclose(fp);
302
return(0);
303
}
304
}
305
}
306
fclose(fp);
307
return (1);
308
}
309
310