summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/ethers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/ethers.c')
-rw-r--r--src/lib/libc/net/ethers.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c
new file mode 100644
index 0000000000..2c1e562245
--- /dev/null
+++ b/src/lib/libc/net/ethers.c
@@ -0,0 +1,247 @@
1/* $OpenBSD: ethers.c,v 1.17 2004/02/16 19:41:12 otto Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * ethers(3) a la Sun.
21 * Originally Written by Roland McGrath <roland@frob.com> 10/14/93.
22 * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com>
23 */
24
25#if defined(LIBC_SCCS) && !defined(lint)
26static char rcsid[] = "$OpenBSD: ethers.c,v 1.17 2004/02/16 19:41:12 otto Exp $";
27#endif /* LIBC_SCCS and not lint */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <netinet/in.h>
33#include <netinet/if_ether.h>
34#include <sys/param.h>
35#include <paths.h>
36#include <errno.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <ctype.h>
41#ifdef YP
42#include <rpcsvc/ypclnt.h>
43#endif
44
45#ifndef _PATH_ETHERS
46#define _PATH_ETHERS "/etc/ethers"
47#endif
48
49static char * _ether_aton(char *, struct ether_addr *);
50
51char *
52ether_ntoa(e)
53 struct ether_addr *e;
54{
55 static char a[] = "xx:xx:xx:xx:xx:xx";
56
57 (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
58 e->ether_addr_octet[0], e->ether_addr_octet[1],
59 e->ether_addr_octet[2], e->ether_addr_octet[3],
60 e->ether_addr_octet[4], e->ether_addr_octet[5]);
61
62 return (a);
63}
64
65static char *
66_ether_aton(s, e)
67 char *s;
68 struct ether_addr *e;
69{
70 int i;
71 long l;
72 char *pp;
73
74 while (isspace(*s))
75 s++;
76
77 /* expect 6 hex octets separated by ':' or space/NUL if last octet */
78 for (i = 0; i < 6; i++) {
79 l = strtol(s, &pp, 16);
80 if (pp == s || l > 0xFF || l < 0)
81 return (NULL);
82 if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
83 return (NULL);
84 e->ether_addr_octet[i] = (u_char)l;
85 s = pp + 1;
86 }
87
88 /* return character after the octets ala strtol(3) */
89 return (pp);
90}
91
92struct ether_addr *
93ether_aton(s)
94 char *s;
95{
96 static struct ether_addr n;
97
98 return (_ether_aton(s, &n) ? &n : NULL);
99}
100
101int
102ether_ntohost(hostname, e)
103 char *hostname;
104 struct ether_addr *e;
105{
106 FILE *f;
107 char buf[BUFSIZ+1], *p;
108 size_t len;
109 struct ether_addr try;
110#ifdef YP
111 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
112 int trylen;
113#endif
114
115#ifdef YP
116 snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
117 e->ether_addr_octet[0], e->ether_addr_octet[1],
118 e->ether_addr_octet[2], e->ether_addr_octet[3],
119 e->ether_addr_octet[4], e->ether_addr_octet[5]);
120 trylen = strlen(trybuf);
121#endif
122
123 f = fopen(_PATH_ETHERS, "r");
124 if (f == NULL)
125 return (-1);
126 while ((p = fgetln(f, &len)) != NULL) {
127 if (p[len-1] == '\n')
128 len--;
129 if (len > sizeof(buf) - 2)
130 continue;
131 (void)memcpy(buf, p, len);
132 buf[len] = '\n'; /* code assumes newlines later on */
133 buf[len+1] = '\0';
134#ifdef YP
135 /* A + in the file means try YP now. */
136 if (!strncmp(buf, "+\n", sizeof(buf))) {
137 char *ypbuf, *ypdom;
138 int ypbuflen;
139
140 if (yp_get_default_domain(&ypdom))
141 continue;
142 if (yp_match(ypdom, "ethers.byaddr", trybuf,
143 trylen, &ypbuf, &ypbuflen))
144 continue;
145 if (ether_line(ypbuf, &try, hostname) == 0) {
146 free(ypbuf);
147 (void)fclose(f);
148 return (0);
149 }
150 free(ypbuf);
151 continue;
152 }
153#endif
154 if (ether_line(buf, &try, hostname) == 0 &&
155 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
156 (void)fclose(f);
157 return (0);
158 }
159 }
160 (void)fclose(f);
161 errno = ENOENT;
162 return (-1);
163}
164
165int
166ether_hostton(hostname, e)
167 char *hostname;
168 struct ether_addr *e;
169{
170 FILE *f;
171 char buf[BUFSIZ+1], *p;
172 char try[MAXHOSTNAMELEN];
173 size_t len;
174#ifdef YP
175 int hostlen = strlen(hostname);
176#endif
177
178 f = fopen(_PATH_ETHERS, "r");
179 if (f==NULL)
180 return (-1);
181
182 while ((p = fgetln(f, &len)) != NULL) {
183 if (p[len-1] == '\n')
184 len--;
185 if (len > sizeof(buf) - 2)
186 continue;
187 memcpy(buf, p, len);
188 buf[len] = '\n'; /* code assumes newlines later on */
189 buf[len+1] = '\0';
190#ifdef YP
191 /* A + in the file means try YP now. */
192 if (!strncmp(buf, "+\n", sizeof(buf))) {
193 char *ypbuf, *ypdom;
194 int ypbuflen;
195
196 if (yp_get_default_domain(&ypdom))
197 continue;
198 if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
199 &ypbuf, &ypbuflen))
200 continue;
201 if (ether_line(ypbuf, e, try) == 0) {
202 free(ypbuf);
203 (void)fclose(f);
204 return (0);
205 }
206 free(ypbuf);
207 continue;
208 }
209#endif
210 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
211 (void)fclose(f);
212 return (0);
213 }
214 }
215 (void)fclose(f);
216 errno = ENOENT;
217 return (-1);
218}
219
220int
221ether_line(line, e, hostname)
222 char *line;
223 struct ether_addr *e;
224 char *hostname;
225{
226 char *p;
227 size_t n;
228
229 /* Parse "xx:xx:xx:xx:xx:xx" */
230 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
231 goto bad;
232
233 /* Now get the hostname */
234 while (isspace(*p))
235 p++;
236 if (*p == '\0')
237 goto bad;
238 n = strcspn(p, " \t\n");
239 if (n >= MAXHOSTNAMELEN)
240 goto bad;
241 strlcpy(hostname, p, n + 1);
242 return (0);
243
244bad:
245 errno = EINVAL;
246 return (-1);
247}