17680d1b0SBill Paul /* 27680d1b0SBill Paul * Copyright (c) 1995 37680d1b0SBill Paul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 47680d1b0SBill Paul * 57680d1b0SBill Paul * Redistribution and use in source and binary forms, with or without 67680d1b0SBill Paul * modification, are permitted provided that the following conditions 77680d1b0SBill Paul * are met: 87680d1b0SBill Paul * 1. Redistributions of source code must retain the above copyright 97680d1b0SBill Paul * notice, this list of conditions and the following disclaimer. 107680d1b0SBill Paul * 2. Redistributions in binary form must reproduce the above copyright 117680d1b0SBill Paul * notice, this list of conditions and the following disclaimer in the 127680d1b0SBill Paul * documentation and/or other materials provided with the distribution. 137680d1b0SBill Paul * 3. All advertising materials mentioning features or use of this software 147680d1b0SBill Paul * must display the following acknowledgement: 157680d1b0SBill Paul * This product includes software developed by Bill Paul. 167680d1b0SBill Paul * 4. Neither the name of the author nor the names of any co-contributors 177680d1b0SBill Paul * may be used to endorse or promote products derived from this software 187680d1b0SBill Paul * without specific prior written permission. 197680d1b0SBill Paul * 207680d1b0SBill Paul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 217680d1b0SBill Paul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 227680d1b0SBill Paul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 237680d1b0SBill Paul * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 247680d1b0SBill Paul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 257680d1b0SBill Paul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 267680d1b0SBill Paul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 277680d1b0SBill Paul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 287680d1b0SBill Paul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 297680d1b0SBill Paul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 307680d1b0SBill Paul * SUCH DAMAGE. 317680d1b0SBill Paul * 327680d1b0SBill Paul * ethernet address conversion and lookup routines 337680d1b0SBill Paul * 347680d1b0SBill Paul * Written by Bill Paul <wpaul@ctr.columbia.edu> 357680d1b0SBill Paul * Center for Telecommunications Research 367680d1b0SBill Paul * Columbia University, New York City 377680d1b0SBill Paul * 383951b8e3SBill Paul * $Id: ether_addr.c,v 1.6 1996/12/10 17:19:09 wollman Exp $ 397680d1b0SBill Paul */ 407680d1b0SBill Paul 417680d1b0SBill Paul 427680d1b0SBill Paul #include <stdio.h> 437680d1b0SBill Paul #include <paths.h> 447680d1b0SBill Paul #include <sys/types.h> 457680d1b0SBill Paul #include <string.h> 467680d1b0SBill Paul #include <stdlib.h> 477680d1b0SBill Paul #include <sys/param.h> 487680d1b0SBill Paul #include <sys/socket.h> 4913629194SGarrett Wollman #include <net/ethernet.h> 507680d1b0SBill Paul #ifdef YP 517680d1b0SBill Paul #include <rpc/rpc.h> 527680d1b0SBill Paul #include <rpcsvc/yp_prot.h> 537680d1b0SBill Paul #include <rpcsvc/ypclnt.h> 547680d1b0SBill Paul #endif 557680d1b0SBill Paul 567680d1b0SBill Paul #ifndef _PATH_ETHERS 577680d1b0SBill Paul #define _PATH_ETHERS "/etc/ethers" 587680d1b0SBill Paul #endif 597680d1b0SBill Paul 607680d1b0SBill Paul /* 617680d1b0SBill Paul * Parse a string of text containing an ethernet address and hostname 627680d1b0SBill Paul * and separate it into its component parts. 637680d1b0SBill Paul */ 647680d1b0SBill Paul int ether_line(l, e, hostname) 657680d1b0SBill Paul char *l; 667680d1b0SBill Paul struct ether_addr *e; 677680d1b0SBill Paul char *hostname; 687680d1b0SBill Paul { 697680d1b0SBill Paul int i, o[6]; 707680d1b0SBill Paul 717680d1b0SBill Paul i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2], 727680d1b0SBill Paul &o[3], &o[4], &o[5], 737680d1b0SBill Paul hostname); 747680d1b0SBill Paul if (i != 7) 757680d1b0SBill Paul return (i); 767680d1b0SBill Paul 777680d1b0SBill Paul for (i=0; i<6; i++) 787680d1b0SBill Paul e->octet[i] = o[i]; 797680d1b0SBill Paul return (0); 807680d1b0SBill Paul } 817680d1b0SBill Paul 827680d1b0SBill Paul /* 837680d1b0SBill Paul * Convert an ASCII representation of an ethernet address to 847680d1b0SBill Paul * binary form. 857680d1b0SBill Paul */ 867680d1b0SBill Paul struct ether_addr *ether_aton(a) 877680d1b0SBill Paul char *a; 887680d1b0SBill Paul { 897680d1b0SBill Paul int i; 907680d1b0SBill Paul static struct ether_addr o; 9151295a4dSJordan K. Hubbard unsigned int o0, o1, o2, o3, o4, o5; 927680d1b0SBill Paul 9351295a4dSJordan K. Hubbard i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5); 9451295a4dSJordan K. Hubbard 957680d1b0SBill Paul if (i != 6) 967680d1b0SBill Paul return (NULL); 9751295a4dSJordan K. Hubbard 9851295a4dSJordan K. Hubbard o.octet[0]=o0; 9951295a4dSJordan K. Hubbard o.octet[1]=o1; 10051295a4dSJordan K. Hubbard o.octet[2]=o2; 10151295a4dSJordan K. Hubbard o.octet[3]=o3; 10251295a4dSJordan K. Hubbard o.octet[4]=o4; 10351295a4dSJordan K. Hubbard o.octet[5]=o5; 10451295a4dSJordan K. Hubbard 1057680d1b0SBill Paul return ((struct ether_addr *)&o); 1067680d1b0SBill Paul } 1077680d1b0SBill Paul 1087680d1b0SBill Paul /* 1097680d1b0SBill Paul * Convert a binary representation of an ethernet address to 1107680d1b0SBill Paul * an ASCII string. 1117680d1b0SBill Paul */ 1127680d1b0SBill Paul char *ether_ntoa(n) 1137680d1b0SBill Paul struct ether_addr *n; 1147680d1b0SBill Paul { 1157680d1b0SBill Paul int i; 1167680d1b0SBill Paul static char a[18]; 1177680d1b0SBill Paul 1187680d1b0SBill Paul i = sprintf(a,"%x:%x:%x:%x:%x:%x",n->octet[0],n->octet[1],n->octet[2], 1197680d1b0SBill Paul n->octet[3],n->octet[4],n->octet[5]); 1207680d1b0SBill Paul if (i < 11) 1217680d1b0SBill Paul return (NULL); 1227680d1b0SBill Paul return ((char *)&a); 1237680d1b0SBill Paul } 1247680d1b0SBill Paul 1257680d1b0SBill Paul /* 1267680d1b0SBill Paul * Map an ethernet address to a hostname. Use either /etc/ethers or 1277680d1b0SBill Paul * NIS/YP. 1287680d1b0SBill Paul */ 1297680d1b0SBill Paul 1307680d1b0SBill Paul int ether_ntohost(hostname, e) 1317680d1b0SBill Paul char *hostname; 1327680d1b0SBill Paul struct ether_addr *e; 1337680d1b0SBill Paul { 1347680d1b0SBill Paul FILE *fp; 1353951b8e3SBill Paul char buf[BUFSIZ + 2]; 1367680d1b0SBill Paul struct ether_addr local_ether; 1377680d1b0SBill Paul char local_host[MAXHOSTNAMELEN]; 1387680d1b0SBill Paul #ifdef YP 1397680d1b0SBill Paul char *result; 1407680d1b0SBill Paul int resultlen; 1417680d1b0SBill Paul char *ether_a; 1427680d1b0SBill Paul char *yp_domain; 1437680d1b0SBill Paul #endif 1447680d1b0SBill Paul if ((fp = fopen(_PATH_ETHERS, "r")) == NULL) 1457680d1b0SBill Paul return (1); 1467680d1b0SBill Paul 1477680d1b0SBill Paul while (fgets(buf,BUFSIZ,fp)) { 1487680d1b0SBill Paul if (buf[0] == '#') 1497680d1b0SBill Paul continue; 1507680d1b0SBill Paul #ifdef YP 1517680d1b0SBill Paul if (buf[0] == '+') { 1527680d1b0SBill Paul if (yp_get_default_domain(&yp_domain)) 1531e890b05SBill Paul continue; 1547680d1b0SBill Paul ether_a = ether_ntoa(e); 1557680d1b0SBill Paul if (yp_match(yp_domain, "ethers.byaddr", ether_a, 1567680d1b0SBill Paul strlen(ether_a), &result, &resultlen)) { 1571e890b05SBill Paul continue; 1587680d1b0SBill Paul } 1592696fe9cSJordan K. Hubbard strncpy(buf, result, resultlen); 1603951b8e3SBill Paul buf[resultlen] = '\0'; 1617680d1b0SBill Paul free(result); 1627680d1b0SBill Paul } 1637680d1b0SBill Paul #endif 1642696fe9cSJordan K. Hubbard if (!ether_line(buf, &local_ether, local_host)) { 1657680d1b0SBill Paul if (!bcmp((char *)&local_ether.octet[0], 1667680d1b0SBill Paul (char *)&e->octet[0], 6)) { 1677680d1b0SBill Paul /* We have a match */ 1682696fe9cSJordan K. Hubbard strcpy(hostname, local_host); 1697680d1b0SBill Paul fclose(fp); 1707680d1b0SBill Paul return(0); 1717680d1b0SBill Paul } 1727680d1b0SBill Paul } 1737680d1b0SBill Paul } 1747680d1b0SBill Paul fclose(fp); 1757680d1b0SBill Paul return (1); 1767680d1b0SBill Paul } 1777680d1b0SBill Paul 1787680d1b0SBill Paul /* 1797680d1b0SBill Paul * Map a hostname to an ethernet address using /etc/ethers or 1807680d1b0SBill Paul * NIS/YP. 1817680d1b0SBill Paul */ 1827680d1b0SBill Paul int ether_hostton(hostname, e) 1837680d1b0SBill Paul char *hostname; 1847680d1b0SBill Paul struct ether_addr *e; 1857680d1b0SBill Paul { 1867680d1b0SBill Paul FILE *fp; 1873951b8e3SBill Paul char buf[BUFSIZ + 2]; 1887680d1b0SBill Paul struct ether_addr local_ether; 1897680d1b0SBill Paul char local_host[MAXHOSTNAMELEN]; 1907680d1b0SBill Paul #ifdef YP 1917680d1b0SBill Paul char *result; 1927680d1b0SBill Paul int resultlen; 1937680d1b0SBill Paul char *yp_domain; 1947680d1b0SBill Paul #endif 1957680d1b0SBill Paul if ((fp = fopen(_PATH_ETHERS, "r")) == NULL) 1967680d1b0SBill Paul return (1); 1977680d1b0SBill Paul 1987680d1b0SBill Paul while (fgets(buf,BUFSIZ,fp)) { 1997680d1b0SBill Paul if (buf[0] == '#') 2007680d1b0SBill Paul continue; 2017680d1b0SBill Paul #ifdef YP 2027680d1b0SBill Paul if (buf[0] == '+') { 2037680d1b0SBill Paul if (yp_get_default_domain(&yp_domain)) 2041e890b05SBill Paul continue; 2057680d1b0SBill Paul if (yp_match(yp_domain, "ethers.byname", hostname, 2067680d1b0SBill Paul strlen(hostname), &result, &resultlen)) { 2071e890b05SBill Paul continue; 2087680d1b0SBill Paul } 2092696fe9cSJordan K. Hubbard strncpy(buf, result, resultlen); 2103951b8e3SBill Paul buf[resultlen] = '\0'; 2117680d1b0SBill Paul free(result); 2127680d1b0SBill Paul } 2137680d1b0SBill Paul #endif 2142696fe9cSJordan K. Hubbard if (!ether_line(buf, &local_ether, local_host)) { 2152696fe9cSJordan K. Hubbard if (!strcmp(hostname, local_host)) { 2167680d1b0SBill Paul /* We have a match */ 2177680d1b0SBill Paul bcopy((char *)&local_ether.octet[0], 2187680d1b0SBill Paul (char *)&e->octet[0], 6); 2197680d1b0SBill Paul fclose(fp); 2207680d1b0SBill Paul return(0); 2217680d1b0SBill Paul } 2227680d1b0SBill Paul } 2237680d1b0SBill Paul } 2247680d1b0SBill Paul fclose(fp); 2257680d1b0SBill Paul return (1); 2267680d1b0SBill Paul } 227