xref: /netbsd-src/lib/libc/net/ethers.c (revision e4d7c2e329d54c97e0c0bd3016bbe74f550c3d5e)
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@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