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 * 3851295a4dSJordan K. Hubbard * $Id: ether_addr.c,v 1.3 1996/03/16 21:25:59 wpaul 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> 497680d1b0SBill Paul #include <net/if.h> 507680d1b0SBill Paul #include <netinet/in.h> 517680d1b0SBill Paul #include <netinet/if_ether.h> 527680d1b0SBill Paul #ifdef YP 537680d1b0SBill Paul #include <rpc/rpc.h> 547680d1b0SBill Paul #include <rpcsvc/yp_prot.h> 557680d1b0SBill Paul #include <rpcsvc/ypclnt.h> 567680d1b0SBill Paul #endif 577680d1b0SBill Paul 587680d1b0SBill Paul #ifndef _PATH_ETHERS 597680d1b0SBill Paul #define _PATH_ETHERS "/etc/ethers" 607680d1b0SBill Paul #endif 617680d1b0SBill Paul 627680d1b0SBill Paul /* 637680d1b0SBill Paul * Parse a string of text containing an ethernet address and hostname 647680d1b0SBill Paul * and separate it into its component parts. 657680d1b0SBill Paul */ 667680d1b0SBill Paul int ether_line(l, e, hostname) 677680d1b0SBill Paul char *l; 687680d1b0SBill Paul struct ether_addr *e; 697680d1b0SBill Paul char *hostname; 707680d1b0SBill Paul { 717680d1b0SBill Paul int i, o[6]; 727680d1b0SBill Paul 737680d1b0SBill Paul i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2], 747680d1b0SBill Paul &o[3], &o[4], &o[5], 757680d1b0SBill Paul hostname); 767680d1b0SBill Paul if (i != 7) 777680d1b0SBill Paul return (i); 787680d1b0SBill Paul 797680d1b0SBill Paul for (i=0; i<6; i++) 807680d1b0SBill Paul e->octet[i] = o[i]; 817680d1b0SBill Paul return (0); 827680d1b0SBill Paul } 837680d1b0SBill Paul 847680d1b0SBill Paul /* 857680d1b0SBill Paul * Convert an ASCII representation of an ethernet address to 867680d1b0SBill Paul * binary form. 877680d1b0SBill Paul */ 887680d1b0SBill Paul struct ether_addr *ether_aton(a) 897680d1b0SBill Paul char *a; 907680d1b0SBill Paul { 917680d1b0SBill Paul int i; 927680d1b0SBill Paul static struct ether_addr o; 9351295a4dSJordan K. Hubbard unsigned int o0, o1, o2, o3, o4, o5; 947680d1b0SBill Paul 9551295a4dSJordan K. Hubbard i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5); 9651295a4dSJordan K. Hubbard 977680d1b0SBill Paul if (i != 6) 987680d1b0SBill Paul return (NULL); 9951295a4dSJordan K. Hubbard 10051295a4dSJordan K. Hubbard o.octet[0]=o0; 10151295a4dSJordan K. Hubbard o.octet[1]=o1; 10251295a4dSJordan K. Hubbard o.octet[2]=o2; 10351295a4dSJordan K. Hubbard o.octet[3]=o3; 10451295a4dSJordan K. Hubbard o.octet[4]=o4; 10551295a4dSJordan K. Hubbard o.octet[5]=o5; 10651295a4dSJordan K. Hubbard 1077680d1b0SBill Paul return ((struct ether_addr *)&o); 1087680d1b0SBill Paul } 1097680d1b0SBill Paul 1107680d1b0SBill Paul /* 1117680d1b0SBill Paul * Convert a binary representation of an ethernet address to 1127680d1b0SBill Paul * an ASCII string. 1137680d1b0SBill Paul */ 1147680d1b0SBill Paul char *ether_ntoa(n) 1157680d1b0SBill Paul struct ether_addr *n; 1167680d1b0SBill Paul { 1177680d1b0SBill Paul int i; 1187680d1b0SBill Paul static char a[18]; 1197680d1b0SBill Paul 1207680d1b0SBill Paul i = sprintf(a,"%x:%x:%x:%x:%x:%x",n->octet[0],n->octet[1],n->octet[2], 1217680d1b0SBill Paul n->octet[3],n->octet[4],n->octet[5]); 1227680d1b0SBill Paul if (i < 11) 1237680d1b0SBill Paul return (NULL); 1247680d1b0SBill Paul return ((char *)&a); 1257680d1b0SBill Paul } 1267680d1b0SBill Paul 1277680d1b0SBill Paul /* 1287680d1b0SBill Paul * Map an ethernet address to a hostname. Use either /etc/ethers or 1297680d1b0SBill Paul * NIS/YP. 1307680d1b0SBill Paul */ 1317680d1b0SBill Paul 1327680d1b0SBill Paul int ether_ntohost(hostname, e) 1337680d1b0SBill Paul char *hostname; 1347680d1b0SBill Paul struct ether_addr *e; 1357680d1b0SBill Paul { 1367680d1b0SBill Paul FILE *fp; 1377680d1b0SBill Paul char buf[BUFSIZ]; 1387680d1b0SBill Paul struct ether_addr local_ether; 1397680d1b0SBill Paul char local_host[MAXHOSTNAMELEN]; 1407680d1b0SBill Paul #ifdef YP 1417680d1b0SBill Paul char *result; 1427680d1b0SBill Paul int resultlen; 1437680d1b0SBill Paul char *ether_a; 1447680d1b0SBill Paul char *yp_domain; 1457680d1b0SBill Paul #endif 1467680d1b0SBill Paul if ((fp = fopen(_PATH_ETHERS, "r")) == NULL) 1477680d1b0SBill Paul return (1); 1487680d1b0SBill Paul 1497680d1b0SBill Paul while (fgets(buf,BUFSIZ,fp)) { 1507680d1b0SBill Paul if (buf[0] == '#') 1517680d1b0SBill Paul continue; 1527680d1b0SBill Paul #ifdef YP 1537680d1b0SBill Paul if (buf[0] == '+') { 1547680d1b0SBill Paul if (yp_get_default_domain(&yp_domain)) 1551e890b05SBill Paul continue; 1567680d1b0SBill Paul ether_a = ether_ntoa(e); 1577680d1b0SBill Paul if (yp_match(yp_domain, "ethers.byaddr", ether_a, 1587680d1b0SBill Paul strlen(ether_a), &result, &resultlen)) { 1591e890b05SBill Paul continue; 1607680d1b0SBill Paul } 1611e890b05SBill Paul strncpy((char *)&buf, result, resultlen); 1627680d1b0SBill Paul free(result); 1637680d1b0SBill Paul } 1647680d1b0SBill Paul #endif 1657680d1b0SBill Paul if (!ether_line(&buf, &local_ether, &local_host)) { 1667680d1b0SBill Paul if (!bcmp((char *)&local_ether.octet[0], 1677680d1b0SBill Paul (char *)&e->octet[0], 6)) { 1687680d1b0SBill Paul /* We have a match */ 1697680d1b0SBill Paul strcpy(hostname, (char *)&local_host); 1707680d1b0SBill Paul fclose(fp); 1717680d1b0SBill Paul return(0); 1727680d1b0SBill Paul } 1737680d1b0SBill Paul } 1747680d1b0SBill Paul } 1757680d1b0SBill Paul fclose(fp); 1767680d1b0SBill Paul return (1); 1777680d1b0SBill Paul } 1787680d1b0SBill Paul 1797680d1b0SBill Paul /* 1807680d1b0SBill Paul * Map a hostname to an ethernet address using /etc/ethers or 1817680d1b0SBill Paul * NIS/YP. 1827680d1b0SBill Paul */ 1837680d1b0SBill Paul int ether_hostton(hostname, e) 1847680d1b0SBill Paul char *hostname; 1857680d1b0SBill Paul struct ether_addr *e; 1867680d1b0SBill Paul { 1877680d1b0SBill Paul FILE *fp; 1887680d1b0SBill Paul char buf[BUFSIZ]; 1897680d1b0SBill Paul struct ether_addr local_ether; 1907680d1b0SBill Paul char local_host[MAXHOSTNAMELEN]; 1917680d1b0SBill Paul #ifdef YP 1927680d1b0SBill Paul char *result; 1937680d1b0SBill Paul int resultlen; 1947680d1b0SBill Paul char *yp_domain; 1957680d1b0SBill Paul #endif 1967680d1b0SBill Paul if ((fp = fopen(_PATH_ETHERS, "r")) == NULL) 1977680d1b0SBill Paul return (1); 1987680d1b0SBill Paul 1997680d1b0SBill Paul while (fgets(buf,BUFSIZ,fp)) { 2007680d1b0SBill Paul if (buf[0] == '#') 2017680d1b0SBill Paul continue; 2027680d1b0SBill Paul #ifdef YP 2037680d1b0SBill Paul if (buf[0] == '+') { 2047680d1b0SBill Paul if (yp_get_default_domain(&yp_domain)) 2051e890b05SBill Paul continue; 2067680d1b0SBill Paul if (yp_match(yp_domain, "ethers.byname", hostname, 2077680d1b0SBill Paul strlen(hostname), &result, &resultlen)) { 2081e890b05SBill Paul continue; 2097680d1b0SBill Paul } 2101e890b05SBill Paul strncpy((char *)&buf, result, resultlen); 2117680d1b0SBill Paul free(result); 2127680d1b0SBill Paul } 2137680d1b0SBill Paul #endif 2147680d1b0SBill Paul if (!ether_line(&buf, &local_ether, &local_host)) { 2157680d1b0SBill Paul if (!strcmp(hostname, (char *)&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