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