Home | History | Annotate | Line # | Download | only in net
ethers.c revision 1.15
      1 /*	$NetBSD: ethers.c,v 1.15 1999/09/16 11:45:11 lukem 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/param.h>
     12 #include <sys/socket.h>
     13 
     14 #include <net/if.h>
     15 #include <net/if_ether.h>
     16 #include <netinet/in.h>
     17 
     18 #include <assert.h>
     19 #include <errno.h>
     20 #include <paths.h>
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 
     25 #ifdef YP
     26 #include <rpcsvc/ypclnt.h>
     27 #endif
     28 
     29 #ifdef __weak_alias
     30 __weak_alias(ether_aton,_ether_aton);
     31 __weak_alias(ether_hostton,_ether_hostton);
     32 __weak_alias(ether_line,_ether_line);
     33 __weak_alias(ether_ntoa,_ether_ntoa);
     34 __weak_alias(ether_ntohost,_ether_ntohost);
     35 #endif
     36 
     37 #ifndef _PATH_ETHERS
     38 #define _PATH_ETHERS "/etc/ethers"
     39 #endif
     40 
     41 char *
     42 ether_ntoa(e)
     43 	struct ether_addr *e;
     44 {
     45 	static char a[18];
     46 
     47 	_DIAGASSERT(e != NULL);
     48 #ifdef _DIAGNOSTIC
     49 	if (e == NULL)
     50 		return NULL;
     51 #endif
     52 
     53 	snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
     54 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
     55 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
     56 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
     57 	return a;
     58 }
     59 
     60 struct ether_addr *
     61 ether_aton(s)
     62 	const char *s;
     63 {
     64 	static struct ether_addr n;
     65 	u_int i[6];
     66 
     67 	_DIAGASSERT(s != NULL);
     68 #ifdef _DIAGNOSTIC
     69 	if (s == NULL)
     70 		return NULL;
     71 #endif
     72 
     73 	if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
     74 	    &i[2], &i[3], &i[4], &i[5]) == 6) {
     75 		n.ether_addr_octet[0] = (u_char)i[0];
     76 		n.ether_addr_octet[1] = (u_char)i[1];
     77 		n.ether_addr_octet[2] = (u_char)i[2];
     78 		n.ether_addr_octet[3] = (u_char)i[3];
     79 		n.ether_addr_octet[4] = (u_char)i[4];
     80 		n.ether_addr_octet[5] = (u_char)i[5];
     81 		return &n;
     82 	}
     83 	return NULL;
     84 }
     85 
     86 int
     87 ether_ntohost(hostname, e)
     88 	char *hostname;
     89 	struct ether_addr *e;
     90 {
     91 	FILE *f;
     92 	char *p;
     93 	size_t len;
     94 	struct ether_addr try;
     95 #ifdef YP
     96 	char trybuf[sizeof "xx:xx:xx:xx:xx:xx"];
     97 	int trylen;
     98 #endif
     99 
    100 	_DIAGASSERT(hostname != NULL);
    101 	_DIAGASSERT(e != NULL);
    102 #ifdef _DIAGNOSTIC
    103 	if (hostname == NULL || e == NULL) {
    104 		errno = EFAULT;
    105 		return -1;
    106 	}
    107 #endif
    108 
    109 #ifdef YP
    110 	trylen = snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
    111 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
    112 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
    113 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
    114 #endif
    115 
    116 	f = fopen(_PATH_ETHERS, "r");
    117 	if (f == NULL)
    118 		return -1;
    119 	while ((p = fgetln(f, &len)) != NULL) {
    120 		if (p[len - 1] != '\n')
    121 			continue;		/* skip lines w/o \n */
    122 		p[--len] = '\0';
    123 #ifdef YP
    124 		/* A + in the file means try YP now.  */
    125 		if (len == 1 && *p == '+') {
    126 			char *ypbuf, *ypdom;
    127 			int ypbuflen;
    128 
    129 			if (yp_get_default_domain(&ypdom))
    130 				continue;
    131 			if (yp_match(ypdom, "ethers.byaddr", trybuf,
    132 			    trylen, &ypbuf, &ypbuflen))
    133 				continue;
    134 			if (ether_line(ypbuf, &try, hostname) == 0) {
    135 				free(ypbuf);
    136 				(void)fclose(f);
    137 				return 0;
    138 			}
    139 			free(ypbuf);
    140 			continue;
    141 		}
    142 #endif
    143 		if (ether_line(p, &try, hostname) == 0 &&
    144 		    memcmp(&try, e, sizeof try) == 0) {
    145 			(void)fclose(f);
    146 			return 0;
    147 		}
    148 	}
    149 	(void)fclose(f);
    150 	errno = ENOENT;
    151 	return -1;
    152 }
    153 
    154 int
    155 ether_hostton(hostname, e)
    156 	const char *hostname;
    157 	struct ether_addr *e;
    158 {
    159 	FILE *f;
    160 	char *p;
    161 	size_t len;
    162 	char try[MAXHOSTNAMELEN + 1];
    163 #ifdef YP
    164 	int hostlen = strlen(hostname);
    165 #endif
    166 
    167 	_DIAGASSERT(hostname != NULL);
    168 	_DIAGASSERT(e != NULL);
    169 #ifdef _DIAGNOSTIC
    170 	if (hostname == NULL || e == NULL) {
    171 		errno = EFAULT;
    172 		return -1;
    173 	}
    174 #endif
    175 
    176 	f = fopen(_PATH_ETHERS, "r");
    177 	if (f==NULL)
    178 		return -1;
    179 
    180 	while ((p = fgetln(f, &len)) != NULL) {
    181 		if (p[len - 1] != '\n')
    182 			continue;		/* skip lines w/o \n */
    183 		p[--len] = '\0';
    184 #ifdef YP
    185 		/* A + in the file means try YP now.  */
    186 		if (len == 1 && *p == '+') {
    187 			char *ypbuf, *ypdom;
    188 			int ypbuflen;
    189 
    190 			if (yp_get_default_domain(&ypdom))
    191 				continue;
    192 			if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
    193 			    &ypbuf, &ypbuflen))
    194 				continue;
    195 			if (ether_line(ypbuf, e, try) == 0) {
    196 				free(ypbuf);
    197 				(void)fclose(f);
    198 				return 0;
    199 			}
    200 			free(ypbuf);
    201 			continue;
    202 		}
    203 #endif
    204 		if (ether_line(p, e, try) == 0 && strcmp(hostname, try) == 0) {
    205 			(void)fclose(f);
    206 			return 0;
    207 		}
    208 	}
    209 	(void)fclose(f);
    210 	errno = ENOENT;
    211 	return -1;
    212 }
    213 
    214 int
    215 ether_line(l, e, hostname)
    216 	const char *l;
    217 	struct ether_addr *e;
    218 	char *hostname;
    219 {
    220 	u_int i[6];
    221 	static char buf[sizeof " %x:%x:%x:%x:%x:%x %s\\n" + 21];
    222 		/* XXX: 21 == strlen (ASCII representation of 2^64) */
    223 
    224 	_DIAGASSERT(l != NULL);
    225 	_DIAGASSERT(e != NULL);
    226 	_DIAGASSERT(hostname != NULL);
    227 #ifdef _DIAGNOSTIC
    228 	if (l == NULL || e == NULL || hostname == NULL) {
    229 		errno = EFAULT;
    230 		return -1;
    231 	}
    232 #endif
    233 
    234 	if (! buf[0])
    235 		snprintf(buf, sizeof buf, " %%x:%%x:%%x:%%x:%%x:%%x %%%ds\\n",
    236 		    MAXHOSTNAMELEN);
    237 	if (sscanf(l, buf,
    238 	    &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], hostname) == 7) {
    239 		e->ether_addr_octet[0] = (u_char)i[0];
    240 		e->ether_addr_octet[1] = (u_char)i[1];
    241 		e->ether_addr_octet[2] = (u_char)i[2];
    242 		e->ether_addr_octet[3] = (u_char)i[3];
    243 		e->ether_addr_octet[4] = (u_char)i[4];
    244 		e->ether_addr_octet[5] = (u_char)i[5];
    245 		return 0;
    246 	}
    247 	errno = EINVAL;
    248 	return -1;
    249 }
    250