Home | History | Annotate | Line # | Download | only in net
ethers.c revision 1.10
      1 /*	$NetBSD: ethers.c,v 1.10 1997/07/21 14:07:52 jtc Exp $	*/
      2 
      3 /*
      4  * ethers(3N) a la Sun.
      5  *
      6  * Written by Roland McGrath <roland (at) frob.com> 10/14/93.
      7  * Public domain.
      8  */
      9 
     10 #include "namespace.h"
     11 #include <sys/types.h>
     12 #include <sys/socket.h>
     13 #include <net/if.h>
     14 #include <net/if_ether.h>
     15 #include <netinet/in.h>
     16 #include <sys/param.h>
     17 #include <paths.h>
     18 #include <errno.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #ifdef YP
     23 #include <rpcsvc/ypclnt.h>
     24 #endif
     25 
     26 #ifdef __weak_alias
     27 __weak_alias(ether_aton,_ether_aton);
     28 __weak_alias(ether_hostton,_ether_hostton);
     29 __weak_alias(ether_line,_ether_line);
     30 __weak_alias(ether_ntoa,_ether_ntoa);
     31 __weak_alias(ether_ntohost,_ether_ntohost);
     32 #endif
     33 
     34 #ifndef _PATH_ETHERS
     35 #define _PATH_ETHERS "/etc/ethers"
     36 #endif
     37 
     38 char *
     39 ether_ntoa(e)
     40 	struct ether_addr *e;
     41 {
     42 	static char a[] = "xx:xx:xx:xx:xx:xx";
     43 
     44 	snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
     45 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
     46 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
     47 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
     48 	return a;
     49 }
     50 
     51 struct ether_addr *
     52 ether_aton(s)
     53 	char *s;
     54 {
     55 	static struct ether_addr n;
     56 	u_int i[6];
     57 
     58 	if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
     59 	    &i[2], &i[3], &i[4], &i[5]) == 6) {
     60 		n.ether_addr_octet[0] = (u_char)i[0];
     61 		n.ether_addr_octet[1] = (u_char)i[1];
     62 		n.ether_addr_octet[2] = (u_char)i[2];
     63 		n.ether_addr_octet[3] = (u_char)i[3];
     64 		n.ether_addr_octet[4] = (u_char)i[4];
     65 		n.ether_addr_octet[5] = (u_char)i[5];
     66 		return &n;
     67 	}
     68 	return NULL;
     69 }
     70 
     71 int
     72 ether_ntohost(hostname, e)
     73 	char *hostname;
     74 	struct ether_addr *e;
     75 {
     76 	FILE *f;
     77 	char buf[BUFSIZ];
     78 	struct ether_addr try;
     79 
     80 #ifdef YP
     81 	char trybuf[sizeof "xx:xx:xx:xx:xx:xx"];
     82 	int trylen;
     83 
     84 	(void)snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
     85 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
     86 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
     87 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
     88 	trylen = strlen(trybuf);
     89 #endif
     90 
     91 	f = fopen(_PATH_ETHERS, "r");
     92 	if (f==NULL)
     93 		return -1;
     94 	while (fgets(buf, sizeof buf, f)) {
     95 #ifdef YP
     96 		/* A + in the file means try YP now.  */
     97 		if (!strncmp(buf, "+\n", sizeof buf)) {
     98 			char *ypbuf, *ypdom;
     99 			int ypbuflen;
    100 
    101 			if (yp_get_default_domain(&ypdom))
    102 				continue;
    103 			if (yp_match(ypdom, "ethers.byaddr", trybuf,
    104 			    trylen, &ypbuf, &ypbuflen))
    105 				continue;
    106 			if (ether_line(ypbuf, &try, hostname) == 0) {
    107 				free(ypbuf);
    108 				(void)fclose(f);
    109 				return 0;
    110 			}
    111 			free(ypbuf);
    112 			continue;
    113 		}
    114 #endif
    115 		if (ether_line(buf, &try, hostname) == 0 &&
    116 		    bcmp((char *)&try, (char *)e, sizeof try) == 0) {
    117 			(void)fclose(f);
    118 			return 0;
    119 		}
    120 	}
    121 	(void)fclose(f);
    122 	errno = ENOENT;
    123 	return -1;
    124 }
    125 
    126 int
    127 ether_hostton(hostname, e)
    128 	char *hostname;
    129 	struct ether_addr *e;
    130 {
    131 	FILE *f;
    132 	char buf[BUFSIZ];
    133 	char try[MAXHOSTNAMELEN];
    134 #ifdef YP
    135 	int hostlen = strlen(hostname);
    136 #endif
    137 
    138 	f = fopen(_PATH_ETHERS, "r");
    139 	if (f==NULL)
    140 		return -1;
    141 
    142 	while (fgets(buf, sizeof buf, f)) {
    143 #ifdef YP
    144 		/* A + in the file means try YP now.  */
    145 		if (!strncmp(buf, "+\n", sizeof buf)) {
    146 			char *ypbuf, *ypdom;
    147 			int ypbuflen;
    148 
    149 			if (yp_get_default_domain(&ypdom))
    150 				continue;
    151 			if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
    152 			    &ypbuf, &ypbuflen))
    153 				continue;
    154 			if (ether_line(ypbuf, e, try) == 0) {
    155 				free(ypbuf);
    156 				(void)fclose(f);
    157 				return 0;
    158 			}
    159 			free(ypbuf);
    160 			continue;
    161 		}
    162 #endif
    163 		if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
    164 			(void)fclose(f);
    165 			return 0;
    166 		}
    167 	}
    168 	(void)fclose(f);
    169 	errno = ENOENT;
    170 	return -1;
    171 }
    172 
    173 int
    174 ether_line(l, e, hostname)
    175 	char *l;
    176 	struct ether_addr *e;
    177 	char *hostname;
    178 {
    179 	u_int i[6];
    180 
    181 	if (sscanf(l, " %x:%x:%x:%x:%x:%x %s\n", &i[0], &i[1],
    182 	    &i[2], &i[3], &i[4], &i[5], hostname) == 7) {
    183 		e->ether_addr_octet[0] = (u_char)i[0];
    184 		e->ether_addr_octet[1] = (u_char)i[1];
    185 		e->ether_addr_octet[2] = (u_char)i[2];
    186 		e->ether_addr_octet[3] = (u_char)i[3];
    187 		e->ether_addr_octet[4] = (u_char)i[4];
    188 		e->ether_addr_octet[5] = (u_char)i[5];
    189 		return 0;
    190 	}
    191 	errno = EINVAL;
    192 	return -1;
    193 }
    194