147a64631SHidetoshi Shimokawa /*
247a64631SHidetoshi Shimokawa * Copyright 2004 The Aerospace Corporation. All rights reserved.
347a64631SHidetoshi Shimokawa *
447a64631SHidetoshi Shimokawa * Redistribution and use in source and binary forms, with or without
547a64631SHidetoshi Shimokawa * modification, are permitted provided that the following conditions
647a64631SHidetoshi Shimokawa * are met:
747a64631SHidetoshi Shimokawa *
847a64631SHidetoshi Shimokawa * 1. Redistributions of source code must retain the above copyright
947a64631SHidetoshi Shimokawa * notice, this list of conditions, and the following disclaimer.
1047a64631SHidetoshi Shimokawa * 2. Redistributions in binary form must reproduce the above copyright
1147a64631SHidetoshi Shimokawa * notice, this list of conditions, and the following disclaimer in the
1247a64631SHidetoshi Shimokawa * documentation and/or other materials provided with the distribution.
1347a64631SHidetoshi Shimokawa * 3. The name of The Aerospace Corporation may not be used to endorse or
1447a64631SHidetoshi Shimokawa * promote products derived from this software.
1547a64631SHidetoshi Shimokawa *
1647a64631SHidetoshi Shimokawa * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
1747a64631SHidetoshi Shimokawa * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1847a64631SHidetoshi Shimokawa * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1947a64631SHidetoshi Shimokawa * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
2047a64631SHidetoshi Shimokawa * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2147a64631SHidetoshi Shimokawa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2247a64631SHidetoshi Shimokawa * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2347a64631SHidetoshi Shimokawa * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2447a64631SHidetoshi Shimokawa * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2547a64631SHidetoshi Shimokawa * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2647a64631SHidetoshi Shimokawa * SUCH DAMAGE.
2747a64631SHidetoshi Shimokawa *
2847a64631SHidetoshi Shimokawa * Copyright (c) 1995
2947a64631SHidetoshi Shimokawa * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
3047a64631SHidetoshi Shimokawa *
3147a64631SHidetoshi Shimokawa * Redistribution and use in source and binary forms, with or without
3247a64631SHidetoshi Shimokawa * modification, are permitted provided that the following conditions
3347a64631SHidetoshi Shimokawa * are met:
3447a64631SHidetoshi Shimokawa * 1. Redistributions of source code must retain the above copyright
3547a64631SHidetoshi Shimokawa * notice, this list of conditions and the following disclaimer.
3647a64631SHidetoshi Shimokawa * 2. Redistributions in binary form must reproduce the above copyright
3747a64631SHidetoshi Shimokawa * notice, this list of conditions and the following disclaimer in the
3847a64631SHidetoshi Shimokawa * documentation and/or other materials provided with the distribution.
3947a64631SHidetoshi Shimokawa * 3. All advertising materials mentioning features or use of this software
4047a64631SHidetoshi Shimokawa * must display the following acknowledgement:
4147a64631SHidetoshi Shimokawa * This product includes software developed by Bill Paul.
4247a64631SHidetoshi Shimokawa * 4. Neither the name of the author nor the names of any co-contributors
4347a64631SHidetoshi Shimokawa * may be used to endorse or promote products derived from this software
4447a64631SHidetoshi Shimokawa * without specific prior written permission.
4547a64631SHidetoshi Shimokawa *
4647a64631SHidetoshi Shimokawa * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
4747a64631SHidetoshi Shimokawa * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4847a64631SHidetoshi Shimokawa * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4947a64631SHidetoshi Shimokawa * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5047a64631SHidetoshi Shimokawa * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5147a64631SHidetoshi Shimokawa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5247a64631SHidetoshi Shimokawa * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5347a64631SHidetoshi Shimokawa * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5447a64631SHidetoshi Shimokawa * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5547a64631SHidetoshi Shimokawa * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5647a64631SHidetoshi Shimokawa * SUCH DAMAGE.
5747a64631SHidetoshi Shimokawa *
5847a64631SHidetoshi Shimokawa * EUI-64 conversion and lookup routines
5947a64631SHidetoshi Shimokawa *
6047a64631SHidetoshi Shimokawa *
6147a64631SHidetoshi Shimokawa * Converted from ether_addr.c rev
6247a64631SHidetoshi Shimokawa * FreeBSD: src/lib/libc/net/eui64.c,v 1.15 2002/04/08 07:51:10 ru Exp
6347a64631SHidetoshi Shimokawa * by Brooks Davis
6447a64631SHidetoshi Shimokawa *
6547a64631SHidetoshi Shimokawa * Written by Bill Paul <wpaul@ctr.columbia.edu>
6647a64631SHidetoshi Shimokawa * Center for Telecommunications Research
6747a64631SHidetoshi Shimokawa * Columbia University, New York City
6847a64631SHidetoshi Shimokawa *
692fbc2f97SSascha Wildner * $FreeBSD: src/lib/libc/net/eui64.c,v 1.2 2004/06/01 19:30:13 brooks Exp $
7047a64631SHidetoshi Shimokawa */
7147a64631SHidetoshi Shimokawa
7247a64631SHidetoshi Shimokawa #include <stdio.h>
7347a64631SHidetoshi Shimokawa #include <paths.h>
7447a64631SHidetoshi Shimokawa #include <sys/types.h>
7547a64631SHidetoshi Shimokawa #include <sys/eui64.h>
7647a64631SHidetoshi Shimokawa #include <string.h>
7747a64631SHidetoshi Shimokawa #include <stdlib.h>
7847a64631SHidetoshi Shimokawa #include <sys/param.h>
7947a64631SHidetoshi Shimokawa #ifdef YP
8047a64631SHidetoshi Shimokawa #include <rpc/rpc.h>
8147a64631SHidetoshi Shimokawa #include <rpcsvc/yp_prot.h>
8247a64631SHidetoshi Shimokawa #include <rpcsvc/ypclnt.h>
8347a64631SHidetoshi Shimokawa #endif
8447a64631SHidetoshi Shimokawa
8547a64631SHidetoshi Shimokawa #ifndef _PATH_EUI64
8647a64631SHidetoshi Shimokawa #define _PATH_EUI64 "/etc/eui64"
8747a64631SHidetoshi Shimokawa #endif
8847a64631SHidetoshi Shimokawa
8947a64631SHidetoshi Shimokawa static int eui64_line(const char *l, struct eui64 *e, char *hostname,
9047a64631SHidetoshi Shimokawa size_t len);
9147a64631SHidetoshi Shimokawa
9247a64631SHidetoshi Shimokawa /*
9347a64631SHidetoshi Shimokawa * Parse a string of text containing an EUI-64 and hostname
9447a64631SHidetoshi Shimokawa * and separate it into its component parts.
9547a64631SHidetoshi Shimokawa */
9647a64631SHidetoshi Shimokawa static int
eui64_line(const char * l,struct eui64 * e,char * hostname,size_t len)9747a64631SHidetoshi Shimokawa eui64_line(const char *l, struct eui64 *e, char *hostname, size_t len)
9847a64631SHidetoshi Shimokawa {
9947a64631SHidetoshi Shimokawa char *line, *linehead, *cur;
10047a64631SHidetoshi Shimokawa
10147a64631SHidetoshi Shimokawa linehead = strdup(l);
10247a64631SHidetoshi Shimokawa if (linehead == NULL)
10347a64631SHidetoshi Shimokawa return (-1);
10447a64631SHidetoshi Shimokawa line = linehead;
10547a64631SHidetoshi Shimokawa
10647a64631SHidetoshi Shimokawa /* Find and parse the EUI64 */
10747a64631SHidetoshi Shimokawa while ((cur = strsep(&line, " \t\r\n")) != NULL) {
10847a64631SHidetoshi Shimokawa if (*cur != '\0') {
10947a64631SHidetoshi Shimokawa if (eui64_aton(cur, e) == 0)
11047a64631SHidetoshi Shimokawa break;
11147a64631SHidetoshi Shimokawa else
11247a64631SHidetoshi Shimokawa goto bad;
11347a64631SHidetoshi Shimokawa }
11447a64631SHidetoshi Shimokawa }
11547a64631SHidetoshi Shimokawa
11647a64631SHidetoshi Shimokawa /* Find the hostname */
11747a64631SHidetoshi Shimokawa while ((cur = strsep(&line, " \t\r\n")) != NULL) {
11847a64631SHidetoshi Shimokawa if (*cur != '\0') {
11947a64631SHidetoshi Shimokawa if (strlcpy(hostname, cur, len) <= len)
12047a64631SHidetoshi Shimokawa break;
12147a64631SHidetoshi Shimokawa else
12247a64631SHidetoshi Shimokawa goto bad;
12347a64631SHidetoshi Shimokawa }
12447a64631SHidetoshi Shimokawa }
12547a64631SHidetoshi Shimokawa
12647a64631SHidetoshi Shimokawa /* Make sure what remains is either whitespace or a comment */
12747a64631SHidetoshi Shimokawa while ((cur = strsep(&line, " \t\r\n")) != NULL) {
12847a64631SHidetoshi Shimokawa if (*cur == '#')
12947a64631SHidetoshi Shimokawa break;
13047a64631SHidetoshi Shimokawa if (*cur != '\0')
13147a64631SHidetoshi Shimokawa goto bad;
13247a64631SHidetoshi Shimokawa }
13347a64631SHidetoshi Shimokawa
13447a64631SHidetoshi Shimokawa return (0);
13547a64631SHidetoshi Shimokawa
13647a64631SHidetoshi Shimokawa bad:
13747a64631SHidetoshi Shimokawa free(linehead);
13847a64631SHidetoshi Shimokawa return (-1);
13947a64631SHidetoshi Shimokawa }
14047a64631SHidetoshi Shimokawa
14147a64631SHidetoshi Shimokawa /*
14247a64631SHidetoshi Shimokawa * Convert an ASCII representation of an EUI-64 to binary form.
14347a64631SHidetoshi Shimokawa */
14447a64631SHidetoshi Shimokawa int
eui64_aton(const char * a,struct eui64 * e)14547a64631SHidetoshi Shimokawa eui64_aton(const char *a, struct eui64 *e)
14647a64631SHidetoshi Shimokawa {
14747a64631SHidetoshi Shimokawa int i;
14847a64631SHidetoshi Shimokawa unsigned int o0, o1, o2, o3, o4, o5, o6, o7;
14947a64631SHidetoshi Shimokawa
15047a64631SHidetoshi Shimokawa /* canonical form */
15147a64631SHidetoshi Shimokawa i = sscanf(a, "%x-%x-%x-%x-%x-%x-%x-%x",
15247a64631SHidetoshi Shimokawa &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
15347a64631SHidetoshi Shimokawa if (i == EUI64_LEN)
15447a64631SHidetoshi Shimokawa goto good;
15547a64631SHidetoshi Shimokawa /* ethernet form */
15647a64631SHidetoshi Shimokawa i = sscanf(a, "%x:%x:%x:%x:%x:%x:%x:%x",
15747a64631SHidetoshi Shimokawa &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
15847a64631SHidetoshi Shimokawa if (i == EUI64_LEN)
15947a64631SHidetoshi Shimokawa goto good;
16047a64631SHidetoshi Shimokawa /* classic fwcontrol/dconschat form */
16147a64631SHidetoshi Shimokawa i = sscanf(a, "0x%2x%2x%2x%2x%2x%2x%2x%2x",
16247a64631SHidetoshi Shimokawa &o0, &o1, &o2, &o3, &o4, &o5, &o6, &o7);
16347a64631SHidetoshi Shimokawa if (i == EUI64_LEN)
16447a64631SHidetoshi Shimokawa goto good;
16547a64631SHidetoshi Shimokawa /* MAC format (-) */
16647a64631SHidetoshi Shimokawa i = sscanf(a, "%x-%x-%x-%x-%x-%x",
16747a64631SHidetoshi Shimokawa &o0, &o1, &o2, &o5, &o6, &o7);
16847a64631SHidetoshi Shimokawa if (i == 6) {
16947a64631SHidetoshi Shimokawa o3 = 0xff;
17047a64631SHidetoshi Shimokawa o4 = 0xfe;
17147a64631SHidetoshi Shimokawa goto good;
17247a64631SHidetoshi Shimokawa }
17347a64631SHidetoshi Shimokawa /* MAC format (:) */
17447a64631SHidetoshi Shimokawa i = sscanf(a, "%x:%x:%x:%x:%x:%x",
17547a64631SHidetoshi Shimokawa &o0, &o1, &o2, &o5, &o6, &o7);
17647a64631SHidetoshi Shimokawa if (i == 6) {
17747a64631SHidetoshi Shimokawa o3 = 0xff;
17847a64631SHidetoshi Shimokawa o4 = 0xfe;
17947a64631SHidetoshi Shimokawa goto good;
18047a64631SHidetoshi Shimokawa }
18147a64631SHidetoshi Shimokawa
18247a64631SHidetoshi Shimokawa return (-1);
18347a64631SHidetoshi Shimokawa
18447a64631SHidetoshi Shimokawa good:
18547a64631SHidetoshi Shimokawa e->octet[0]=o0;
18647a64631SHidetoshi Shimokawa e->octet[1]=o1;
18747a64631SHidetoshi Shimokawa e->octet[2]=o2;
18847a64631SHidetoshi Shimokawa e->octet[3]=o3;
18947a64631SHidetoshi Shimokawa e->octet[4]=o4;
19047a64631SHidetoshi Shimokawa e->octet[5]=o5;
19147a64631SHidetoshi Shimokawa e->octet[6]=o6;
19247a64631SHidetoshi Shimokawa e->octet[7]=o7;
19347a64631SHidetoshi Shimokawa
19447a64631SHidetoshi Shimokawa return (0);
19547a64631SHidetoshi Shimokawa }
19647a64631SHidetoshi Shimokawa
19747a64631SHidetoshi Shimokawa /*
19847a64631SHidetoshi Shimokawa * Convert a binary representation of an EUI-64 to an ASCII string.
19947a64631SHidetoshi Shimokawa */
20047a64631SHidetoshi Shimokawa int
eui64_ntoa(const struct eui64 * id,char * a,size_t len)20147a64631SHidetoshi Shimokawa eui64_ntoa(const struct eui64 *id, char *a, size_t len)
20247a64631SHidetoshi Shimokawa {
20347a64631SHidetoshi Shimokawa int i;
20447a64631SHidetoshi Shimokawa
20547a64631SHidetoshi Shimokawa i = snprintf(a, len, "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
20647a64631SHidetoshi Shimokawa id->octet[0], id->octet[1], id->octet[2], id->octet[3],
20747a64631SHidetoshi Shimokawa id->octet[4], id->octet[5], id->octet[6], id->octet[7]);
20847a64631SHidetoshi Shimokawa if (i < 23 || i >= len)
20947a64631SHidetoshi Shimokawa return (-1);
21047a64631SHidetoshi Shimokawa return (0);
21147a64631SHidetoshi Shimokawa }
21247a64631SHidetoshi Shimokawa
21347a64631SHidetoshi Shimokawa /*
21447a64631SHidetoshi Shimokawa * Map an EUI-64 to a hostname. Use either /etc/eui64 or NIS/YP.
21547a64631SHidetoshi Shimokawa */
21647a64631SHidetoshi Shimokawa int
eui64_ntohost(char * hostname,size_t len __unused,const struct eui64 * id)217*6d7019e6SSascha Wildner eui64_ntohost(char *hostname, size_t len __unused, const struct eui64 *id)
21847a64631SHidetoshi Shimokawa {
21947a64631SHidetoshi Shimokawa FILE *fp;
22047a64631SHidetoshi Shimokawa char buf[BUFSIZ + 2];
22147a64631SHidetoshi Shimokawa struct eui64 local_eui64;
22247a64631SHidetoshi Shimokawa char local_host[MAXHOSTNAMELEN];
22347a64631SHidetoshi Shimokawa #ifdef YP
22447a64631SHidetoshi Shimokawa char *result;
22547a64631SHidetoshi Shimokawa int resultlen;
22647a64631SHidetoshi Shimokawa char eui64_a[24];
22747a64631SHidetoshi Shimokawa char *yp_domain;
22847a64631SHidetoshi Shimokawa #endif
22947a64631SHidetoshi Shimokawa if ((fp = fopen(_PATH_EUI64, "r")) == NULL)
23047a64631SHidetoshi Shimokawa return (1);
23147a64631SHidetoshi Shimokawa
23247a64631SHidetoshi Shimokawa while (fgets(buf,BUFSIZ,fp)) {
23347a64631SHidetoshi Shimokawa if (buf[0] == '#')
23447a64631SHidetoshi Shimokawa continue;
23547a64631SHidetoshi Shimokawa #ifdef YP
23647a64631SHidetoshi Shimokawa if (buf[0] == '+') {
23747a64631SHidetoshi Shimokawa if (yp_get_default_domain(&yp_domain))
23847a64631SHidetoshi Shimokawa continue;
23947a64631SHidetoshi Shimokawa eui64_ntoa(id, eui64_a, sizeof(eui64_a));
24047a64631SHidetoshi Shimokawa if (yp_match(yp_domain, "eui64.byid", eui64_a,
24147a64631SHidetoshi Shimokawa strlen(eui64_a), &result, &resultlen)) {
24247a64631SHidetoshi Shimokawa continue;
24347a64631SHidetoshi Shimokawa }
24447a64631SHidetoshi Shimokawa strncpy(buf, result, resultlen);
24547a64631SHidetoshi Shimokawa buf[resultlen] = '\0';
24647a64631SHidetoshi Shimokawa free(result);
24747a64631SHidetoshi Shimokawa }
24847a64631SHidetoshi Shimokawa #endif
24947a64631SHidetoshi Shimokawa if (eui64_line(buf, &local_eui64, local_host,
25047a64631SHidetoshi Shimokawa sizeof(local_host)) == 0) {
25147a64631SHidetoshi Shimokawa if (bcmp(&local_eui64.octet[0],
25247a64631SHidetoshi Shimokawa &id->octet[0], EUI64_LEN) == 0) {
25347a64631SHidetoshi Shimokawa /* We have a match */
25447a64631SHidetoshi Shimokawa strcpy(hostname, local_host);
25547a64631SHidetoshi Shimokawa fclose(fp);
25647a64631SHidetoshi Shimokawa return(0);
25747a64631SHidetoshi Shimokawa }
25847a64631SHidetoshi Shimokawa }
25947a64631SHidetoshi Shimokawa }
26047a64631SHidetoshi Shimokawa fclose(fp);
26147a64631SHidetoshi Shimokawa return (1);
26247a64631SHidetoshi Shimokawa }
26347a64631SHidetoshi Shimokawa
26447a64631SHidetoshi Shimokawa /*
26547a64631SHidetoshi Shimokawa * Map a hostname to an EUI-64 using /etc/eui64 or NIS/YP.
26647a64631SHidetoshi Shimokawa */
26747a64631SHidetoshi Shimokawa int
eui64_hostton(const char * hostname,struct eui64 * id)26847a64631SHidetoshi Shimokawa eui64_hostton(const char *hostname, struct eui64 *id)
26947a64631SHidetoshi Shimokawa {
27047a64631SHidetoshi Shimokawa FILE *fp;
27147a64631SHidetoshi Shimokawa char buf[BUFSIZ + 2];
27247a64631SHidetoshi Shimokawa struct eui64 local_eui64;
27347a64631SHidetoshi Shimokawa char local_host[MAXHOSTNAMELEN];
27447a64631SHidetoshi Shimokawa #ifdef YP
27547a64631SHidetoshi Shimokawa char *result;
27647a64631SHidetoshi Shimokawa int resultlen;
27747a64631SHidetoshi Shimokawa char *yp_domain;
27847a64631SHidetoshi Shimokawa #endif
27947a64631SHidetoshi Shimokawa if ((fp = fopen(_PATH_EUI64, "r")) == NULL)
28047a64631SHidetoshi Shimokawa return (1);
28147a64631SHidetoshi Shimokawa
28247a64631SHidetoshi Shimokawa while (fgets(buf,BUFSIZ,fp)) {
28347a64631SHidetoshi Shimokawa if (buf[0] == '#')
28447a64631SHidetoshi Shimokawa continue;
28547a64631SHidetoshi Shimokawa #ifdef YP
28647a64631SHidetoshi Shimokawa if (buf[0] == '+') {
28747a64631SHidetoshi Shimokawa if (yp_get_default_domain(&yp_domain))
28847a64631SHidetoshi Shimokawa continue;
28947a64631SHidetoshi Shimokawa if (yp_match(yp_domain, "eui64.byname", hostname,
29047a64631SHidetoshi Shimokawa strlen(hostname), &result, &resultlen)) {
29147a64631SHidetoshi Shimokawa continue;
29247a64631SHidetoshi Shimokawa }
29347a64631SHidetoshi Shimokawa strncpy(buf, result, resultlen);
29447a64631SHidetoshi Shimokawa buf[resultlen] = '\0';
29547a64631SHidetoshi Shimokawa free(result);
29647a64631SHidetoshi Shimokawa }
29747a64631SHidetoshi Shimokawa #endif
29847a64631SHidetoshi Shimokawa if (eui64_line(buf, &local_eui64, local_host,
29947a64631SHidetoshi Shimokawa sizeof(local_host)) == 0) {
30047a64631SHidetoshi Shimokawa if (strcmp(hostname, local_host) == 0) {
30147a64631SHidetoshi Shimokawa /* We have a match */
30247a64631SHidetoshi Shimokawa bcopy(&local_eui64, id, sizeof(struct eui64));
30347a64631SHidetoshi Shimokawa fclose(fp);
30447a64631SHidetoshi Shimokawa return(0);
30547a64631SHidetoshi Shimokawa }
30647a64631SHidetoshi Shimokawa }
30747a64631SHidetoshi Shimokawa }
30847a64631SHidetoshi Shimokawa fclose(fp);
30947a64631SHidetoshi Shimokawa return (1);
31047a64631SHidetoshi Shimokawa }
311