Home | History | Annotate | Line # | Download | only in net
ethers.c revision 1.14
      1 /*	$NetBSD: ethers.c,v 1.14 1998/11/13 15:46:53 christos 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[18];
     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 	const 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 *p;
     78 	size_t len;
     79 	struct ether_addr try;
     80 
     81 #ifdef YP
     82 	char trybuf[sizeof "xx:xx:xx:xx:xx:xx"];
     83 	int trylen;
     84 
     85 	trylen = snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
     86 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
     87 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
     88 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
     89 #endif
     90 
     91 	f = fopen(_PATH_ETHERS, "r");
     92 	if (f == NULL)
     93 		return -1;
     94 	while ((p = fgetln(f, &len)) != NULL) {
     95 		if (p[len - 1] != '\n')
     96 			continue;		/* skip lines w/o \n */
     97 		p[--len] = '\0';
     98 #ifdef YP
     99 		/* A + in the file means try YP now.  */
    100 		if (len == 1 && *p == '+') {
    101 			char *ypbuf, *ypdom;
    102 			int ypbuflen;
    103 
    104 			if (yp_get_default_domain(&ypdom))
    105 				continue;
    106 			if (yp_match(ypdom, "ethers.byaddr", trybuf,
    107 			    trylen, &ypbuf, &ypbuflen))
    108 				continue;
    109 			if (ether_line(ypbuf, &try, hostname) == 0) {
    110 				free(ypbuf);
    111 				(void)fclose(f);
    112 				return 0;
    113 			}
    114 			free(ypbuf);
    115 			continue;
    116 		}
    117 #endif
    118 		if (ether_line(p, &try, hostname) == 0 &&
    119 		    memcmp(&try, e, sizeof try) == 0) {
    120 			(void)fclose(f);
    121 			return 0;
    122 		}
    123 	}
    124 	(void)fclose(f);
    125 	errno = ENOENT;
    126 	return -1;
    127 }
    128 
    129 int
    130 ether_hostton(hostname, e)
    131 	const char *hostname;
    132 	struct ether_addr *e;
    133 {
    134 	FILE *f;
    135 	char *p;
    136 	size_t len;
    137 	char try[MAXHOSTNAMELEN + 1];
    138 #ifdef YP
    139 	int hostlen = strlen(hostname);
    140 #endif
    141 
    142 	f = fopen(_PATH_ETHERS, "r");
    143 	if (f==NULL)
    144 		return -1;
    145 
    146 	while ((p = fgetln(f, &len)) != NULL) {
    147 		if (p[len - 1] != '\n')
    148 			continue;		/* skip lines w/o \n */
    149 		p[--len] = '\0';
    150 #ifdef YP
    151 		/* A + in the file means try YP now.  */
    152 		if (len == 1 && *p == '+') {
    153 			char *ypbuf, *ypdom;
    154 			int ypbuflen;
    155 
    156 			if (yp_get_default_domain(&ypdom))
    157 				continue;
    158 			if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
    159 			    &ypbuf, &ypbuflen))
    160 				continue;
    161 			if (ether_line(ypbuf, e, try) == 0) {
    162 				free(ypbuf);
    163 				(void)fclose(f);
    164 				return 0;
    165 			}
    166 			free(ypbuf);
    167 			continue;
    168 		}
    169 #endif
    170 		if (ether_line(p, e, try) == 0 && strcmp(hostname, try) == 0) {
    171 			(void)fclose(f);
    172 			return 0;
    173 		}
    174 	}
    175 	(void)fclose(f);
    176 	errno = ENOENT;
    177 	return -1;
    178 }
    179 
    180 int
    181 ether_line(l, e, hostname)
    182 	const char *l;
    183 	struct ether_addr *e;
    184 	char *hostname;
    185 {
    186 	u_int i[6];
    187 	static char buf[sizeof " %x:%x:%x:%x:%x:%x %s\\n" + 21];
    188 		/* XXX: 21 == strlen (ASCII representation of 2^64) */
    189 
    190 	if (! buf[0])
    191 		snprintf(buf, sizeof buf, " %%x:%%x:%%x:%%x:%%x:%%x %%%ds\\n",
    192 		    MAXHOSTNAMELEN);
    193 	if (sscanf(l, buf,
    194 	    &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], hostname) == 7) {
    195 		e->ether_addr_octet[0] = (u_char)i[0];
    196 		e->ether_addr_octet[1] = (u_char)i[1];
    197 		e->ether_addr_octet[2] = (u_char)i[2];
    198 		e->ether_addr_octet[3] = (u_char)i[3];
    199 		e->ether_addr_octet[4] = (u_char)i[4];
    200 		e->ether_addr_octet[5] = (u_char)i[5];
    201 		return 0;
    202 	}
    203 	errno = EINVAL;
    204 	return -1;
    205 }
    206