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.c234
1 files changed, 234 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..af31bb8e60
--- /dev/null
+++ b/src/lib/libc/net/ethers.c
@@ -0,0 +1,234 @@
1/* $OpenBSD: ethers.c,v 1.21 2013/11/24 23:51:28 deraadt 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#include <sys/types.h>
26#include <sys/socket.h>
27#include <net/if.h>
28#include <netinet/in.h>
29#include <netinet/if_ether.h>
30#include <sys/param.h>
31#include <paths.h>
32#include <errno.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <ctype.h>
37#ifdef YP
38#include <rpcsvc/ypclnt.h>
39#endif
40
41#ifndef _PATH_ETHERS
42#define _PATH_ETHERS "/etc/ethers"
43#endif
44
45static char * _ether_aton(const char *, struct ether_addr *);
46
47char *
48ether_ntoa(struct ether_addr *e)
49{
50 static char a[] = "xx:xx:xx:xx:xx:xx";
51
52 (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
53 e->ether_addr_octet[0], e->ether_addr_octet[1],
54 e->ether_addr_octet[2], e->ether_addr_octet[3],
55 e->ether_addr_octet[4], e->ether_addr_octet[5]);
56
57 return (a);
58}
59
60static char *
61_ether_aton(const char *s, struct ether_addr *e)
62{
63 int i;
64 long l;
65 char *pp;
66
67 while (isspace((unsigned char)*s))
68 s++;
69
70 /* expect 6 hex octets separated by ':' or space/NUL if last octet */
71 for (i = 0; i < 6; i++) {
72 l = strtol(s, &pp, 16);
73 if (pp == s || l > 0xFF || l < 0)
74 return (NULL);
75 if (!(*pp == ':' ||
76 (i == 5 && (isspace((unsigned char)*pp) ||
77 *pp == '\0'))))
78 return (NULL);
79 e->ether_addr_octet[i] = (u_char)l;
80 s = pp + 1;
81 }
82
83 /* return character after the octets ala strtol(3) */
84 return (pp);
85}
86
87struct ether_addr *
88ether_aton(const char *s)
89{
90 static struct ether_addr n;
91
92 return (_ether_aton(s, &n) ? &n : NULL);
93}
94
95int
96ether_ntohost(char *hostname, struct ether_addr *e)
97{
98 FILE *f;
99 char buf[BUFSIZ+1], *p;
100 size_t len;
101 struct ether_addr try;
102#ifdef YP
103 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
104 int trylen;
105#endif
106
107#ifdef YP
108 snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
109 e->ether_addr_octet[0], e->ether_addr_octet[1],
110 e->ether_addr_octet[2], e->ether_addr_octet[3],
111 e->ether_addr_octet[4], e->ether_addr_octet[5]);
112 trylen = strlen(trybuf);
113#endif
114
115 f = fopen(_PATH_ETHERS, "r");
116 if (f == NULL)
117 return (-1);
118 while ((p = fgetln(f, &len)) != NULL) {
119 if (p[len-1] == '\n')
120 len--;
121 if (len > sizeof(buf) - 2)
122 continue;
123 (void)memcpy(buf, p, len);
124 buf[len] = '\n'; /* code assumes newlines later on */
125 buf[len+1] = '\0';
126#ifdef YP
127 /* A + in the file means try YP now. */
128 if (!strncmp(buf, "+\n", sizeof(buf))) {
129 char *ypbuf, *ypdom;
130 int ypbuflen;
131
132 if (yp_get_default_domain(&ypdom))
133 continue;
134 if (yp_match(ypdom, "ethers.byaddr", trybuf,
135 trylen, &ypbuf, &ypbuflen))
136 continue;
137 if (ether_line(ypbuf, &try, hostname) == 0) {
138 free(ypbuf);
139 (void)fclose(f);
140 return (0);
141 }
142 free(ypbuf);
143 continue;
144 }
145#endif
146 if (ether_line(buf, &try, hostname) == 0 &&
147 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
148 (void)fclose(f);
149 return (0);
150 }
151 }
152 (void)fclose(f);
153 errno = ENOENT;
154 return (-1);
155}
156
157int
158ether_hostton(const char *hostname, struct ether_addr *e)
159{
160 FILE *f;
161 char buf[BUFSIZ+1], *p;
162 char try[MAXHOSTNAMELEN];
163 size_t len;
164#ifdef YP
165 int hostlen = strlen(hostname);
166#endif
167
168 f = fopen(_PATH_ETHERS, "r");
169 if (f==NULL)
170 return (-1);
171
172 while ((p = fgetln(f, &len)) != NULL) {
173 if (p[len-1] == '\n')
174 len--;
175 if (len > sizeof(buf) - 2)
176 continue;
177 memcpy(buf, p, len);
178 buf[len] = '\n'; /* code assumes newlines later on */
179 buf[len+1] = '\0';
180#ifdef YP
181 /* A + in the file means try YP now. */
182 if (!strncmp(buf, "+\n", sizeof(buf))) {
183 char *ypbuf, *ypdom;
184 int ypbuflen;
185
186 if (yp_get_default_domain(&ypdom))
187 continue;
188 if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
189 &ypbuf, &ypbuflen))
190 continue;
191 if (ether_line(ypbuf, e, try) == 0) {
192 free(ypbuf);
193 (void)fclose(f);
194 return (0);
195 }
196 free(ypbuf);
197 continue;
198 }
199#endif
200 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
201 (void)fclose(f);
202 return (0);
203 }
204 }
205 (void)fclose(f);
206 errno = ENOENT;
207 return (-1);
208}
209
210int
211ether_line(const char *line, struct ether_addr *e, char *hostname)
212{
213 char *p;
214 size_t n;
215
216 /* Parse "xx:xx:xx:xx:xx:xx" */
217 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
218 goto bad;
219
220 /* Now get the hostname */
221 while (isspace((unsigned char)*p))
222 p++;
223 if (*p == '\0')
224 goto bad;
225 n = strcspn(p, " \t\n");
226 if (n >= MAXHOSTNAMELEN)
227 goto bad;
228 strlcpy(hostname, p, n + 1);
229 return (0);
230
231bad:
232 errno = EINVAL;
233 return (-1);
234}