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