Home | History | Annotate | Line # | Download | only in net
ethers.c revision 1.17
      1 /*	$NetBSD: ethers.c,v 1.17 2000/01/22 22:19:14 mycroft 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 
     49 	snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
     50 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
     51 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
     52 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
     53 	return a;
     54 }
     55 
     56 struct ether_addr *
     57 ether_aton(s)
     58 	const char *s;
     59 {
     60 	static struct ether_addr n;
     61 	u_int i[6];
     62 
     63 	_DIAGASSERT(s != NULL);
     64 
     65 	if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
     66 	    &i[2], &i[3], &i[4], &i[5]) == 6) {
     67 		n.ether_addr_octet[0] = (u_char)i[0];
     68 		n.ether_addr_octet[1] = (u_char)i[1];
     69 		n.ether_addr_octet[2] = (u_char)i[2];
     70 		n.ether_addr_octet[3] = (u_char)i[3];
     71 		n.ether_addr_octet[4] = (u_char)i[4];
     72 		n.ether_addr_octet[5] = (u_char)i[5];
     73 		return &n;
     74 	}
     75 	return NULL;
     76 }
     77 
     78 int
     79 ether_ntohost(hostname, e)
     80 	char *hostname;
     81 	struct ether_addr *e;
     82 {
     83 	FILE *f;
     84 	char *p;
     85 	size_t len;
     86 	struct ether_addr try;
     87 #ifdef YP
     88 	char trybuf[sizeof "xx:xx:xx:xx:xx:xx"];
     89 	int trylen;
     90 #endif
     91 
     92 	_DIAGASSERT(hostname != NULL);
     93 	_DIAGASSERT(e != NULL);
     94 
     95 #ifdef YP
     96 	trylen = snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
     97 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
     98 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
     99 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
    100 #endif
    101 
    102 	f = fopen(_PATH_ETHERS, "r");
    103 	if (f == NULL)
    104 		return -1;
    105 	while ((p = fgetln(f, &len)) != NULL) {
    106 		if (p[len - 1] != '\n')
    107 			continue;		/* skip lines w/o \n */
    108 		p[--len] = '\0';
    109 #ifdef YP
    110 		/* A + in the file means try YP now.  */
    111 		if (len == 1 && *p == '+') {
    112 			char *ypbuf, *ypdom;
    113 			int ypbuflen;
    114 
    115 			if (yp_get_default_domain(&ypdom))
    116 				continue;
    117 			if (yp_match(ypdom, "ethers.byaddr", trybuf,
    118 			    trylen, &ypbuf, &ypbuflen))
    119 				continue;
    120 			if (ether_line(ypbuf, &try, hostname) == 0) {
    121 				free(ypbuf);
    122 				(void)fclose(f);
    123 				return 0;
    124 			}
    125 			free(ypbuf);
    126 			continue;
    127 		}
    128 #endif
    129 		if (ether_line(p, &try, hostname) == 0 &&
    130 		    memcmp(&try, e, sizeof try) == 0) {
    131 			(void)fclose(f);
    132 			return 0;
    133 		}
    134 	}
    135 	(void)fclose(f);
    136 	errno = ENOENT;
    137 	return -1;
    138 }
    139 
    140 int
    141 ether_hostton(hostname, e)
    142 	const char *hostname;
    143 	struct ether_addr *e;
    144 {
    145 	FILE *f;
    146 	char *p;
    147 	size_t len;
    148 	char try[MAXHOSTNAMELEN + 1];
    149 #ifdef YP
    150 	int hostlen = strlen(hostname);
    151 #endif
    152 
    153 	_DIAGASSERT(hostname != NULL);
    154 	_DIAGASSERT(e != NULL);
    155 
    156 	f = fopen(_PATH_ETHERS, "r");
    157 	if (f==NULL)
    158 		return -1;
    159 
    160 	while ((p = fgetln(f, &len)) != NULL) {
    161 		if (p[len - 1] != '\n')
    162 			continue;		/* skip lines w/o \n */
    163 		p[--len] = '\0';
    164 #ifdef YP
    165 		/* A + in the file means try YP now.  */
    166 		if (len == 1 && *p == '+') {
    167 			char *ypbuf, *ypdom;
    168 			int ypbuflen;
    169 
    170 			if (yp_get_default_domain(&ypdom))
    171 				continue;
    172 			if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
    173 			    &ypbuf, &ypbuflen))
    174 				continue;
    175 			if (ether_line(ypbuf, e, try) == 0) {
    176 				free(ypbuf);
    177 				(void)fclose(f);
    178 				return 0;
    179 			}
    180 			free(ypbuf);
    181 			continue;
    182 		}
    183 #endif
    184 		if (ether_line(p, e, try) == 0 && strcmp(hostname, try) == 0) {
    185 			(void)fclose(f);
    186 			return 0;
    187 		}
    188 	}
    189 	(void)fclose(f);
    190 	errno = ENOENT;
    191 	return -1;
    192 }
    193 
    194 int
    195 ether_line(l, e, hostname)
    196 	const char *l;
    197 	struct ether_addr *e;
    198 	char *hostname;
    199 {
    200 	u_int i[6];
    201 	static char buf[sizeof " %x:%x:%x:%x:%x:%x %s\\n" + 21];
    202 		/* XXX: 21 == strlen (ASCII representation of 2^64) */
    203 
    204 	_DIAGASSERT(l != NULL);
    205 	_DIAGASSERT(e != NULL);
    206 	_DIAGASSERT(hostname != NULL);
    207 
    208 	if (! buf[0])
    209 		snprintf(buf, sizeof buf, " %%x:%%x:%%x:%%x:%%x:%%x %%%ds\\n",
    210 		    MAXHOSTNAMELEN);
    211 	if (sscanf(l, buf,
    212 	    &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], hostname) == 7) {
    213 		e->ether_addr_octet[0] = (u_char)i[0];
    214 		e->ether_addr_octet[1] = (u_char)i[1];
    215 		e->ether_addr_octet[2] = (u_char)i[2];
    216 		e->ether_addr_octet[3] = (u_char)i[3];
    217 		e->ether_addr_octet[4] = (u_char)i[4];
    218 		e->ether_addr_octet[5] = (u_char)i[5];
    219 		return 0;
    220 	}
    221 	errno = EINVAL;
    222 	return -1;
    223 }
    224