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