xref: /openbsd-src/lib/libc/net/ethers.c (revision aff2b1e41ca918d7aeda7a2263889387c0ad437d)
1 /*
2  * ethers(3N) a la Sun.
3  *
4  * Written by Roland McGrath <roland@frob.com> 10/14/93.
5  * Public domain.
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char rcsid[] = "$OpenBSD: ethers.c,v 1.4 1998/03/16 05:06:53 millert Exp $";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <net/if.h>
15 #include <netinet/in.h>
16 #include <netinet/if_ether.h>
17 #include <sys/param.h>
18 #include <paths.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #ifndef _PATH_ETHERS
25 #define _PATH_ETHERS "/etc/ethers"
26 #endif
27 
28 char *
29 ether_ntoa(e)
30 	struct ether_addr *e;
31 {
32 	static char a[] = "xx:xx:xx:xx:xx:xx";
33 
34 	sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x",
35 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
36 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
37 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
38 	return a;
39 }
40 
41 struct ether_addr *
42 ether_aton(s)
43 	char *s;
44 {
45 	static struct ether_addr n;
46 	u_int i[6];
47 
48 	if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
49 	    &i[2], &i[3], &i[4], &i[5]) == 6) {
50 		n.ether_addr_octet[0] = (u_char)i[0];
51 		n.ether_addr_octet[1] = (u_char)i[1];
52 		n.ether_addr_octet[2] = (u_char)i[2];
53 		n.ether_addr_octet[3] = (u_char)i[3];
54 		n.ether_addr_octet[4] = (u_char)i[4];
55 		n.ether_addr_octet[5] = (u_char)i[5];
56 		return &n;
57 	}
58 	return NULL;
59 }
60 
61 int
62 ether_ntohost(hostname, e)
63 	char *hostname;
64 	struct ether_addr *e;
65 {
66 	FILE *f;
67 	char buf[BUFSIZ+1], *p;
68 	size_t len;
69 	struct ether_addr try;
70 
71 #ifdef YP
72 	char trybuf[sizeof "xx:xx:xx:xx:xx:xx"];
73 	int trylen;
74 
75 	sprintf(trybuf, "%x:%x:%x:%x:%x:%x",
76 	    e->ether_addr_octet[0], e->ether_addr_octet[1],
77 	    e->ether_addr_octet[2], e->ether_addr_octet[3],
78 	    e->ether_addr_octet[4], e->ether_addr_octet[5]);
79 	trylen = strlen(trybuf);
80 #endif
81 
82 	f = fopen(_PATH_ETHERS, "r");
83 	if (f == NULL)
84 		return -1;
85 	while ((p = fgetln(f, &len)) != NULL) {
86 		if (p[len-1] == '\n')
87 			len--;
88 		if (len > sizeof(buf) - 2)
89 			continue;
90 		memcpy(buf, p, len);
91 		buf[len] = '\n';	/* code assumes newlines later on */
92 		buf[len+1] = '\0';
93 #ifdef YP
94 		/* A + in the file means try YP now.  */
95 		if (!strncmp(buf, "+\n", sizeof buf)) {
96 			char *ypbuf, *ypdom;
97 			int ypbuflen;
98 
99 			if (yp_get_default_domain(&ypdom))
100 				continue;
101 			if (yp_match(ypdom, "ethers.byaddr", trybuf,
102 			    trylen, &ypbuf, &ypbuflen))
103 				continue;
104 			if (ether_line(ypbuf, &try, hostname) == 0) {
105 				free(ypbuf);
106 				(void)fclose(f);
107 				return 0;
108 			}
109 			free(ypbuf);
110 			continue;
111 		}
112 #endif
113 		if (ether_line(buf, &try, hostname) == 0 &&
114 		    memcmp((char *)&try, (char *)e, sizeof try) == 0) {
115 			(void)fclose(f);
116 			return 0;
117 		}
118 	}
119 	(void)fclose(f);
120 	errno = ENOENT;
121 	return -1;
122 }
123 
124 int
125 ether_hostton(hostname, e)
126 	char *hostname;
127 	struct ether_addr *e;
128 {
129 	FILE *f;
130 	char buf[BUFSIZ+1], *p;
131 	char try[MAXHOSTNAMELEN];
132 	size_t len;
133 #ifdef YP
134 	int hostlen = strlen(hostname);
135 #endif
136 
137 	f = fopen(_PATH_ETHERS, "r");
138 	if (f==NULL)
139 		return -1;
140 
141 	while ((p = fgetln(f, &len)) != NULL) {
142 		if (p[len-1] == '\n')
143 			len--;
144 		if (len > sizeof(buf) - 2)
145 			continue;
146 		memcpy(buf, p, len);
147 		buf[len] = '\n';	/* code assumes newlines later on */
148 		buf[len+1] = '\0';
149 #ifdef YP
150 		/* A + in the file means try YP now.  */
151 		if (!strncmp(buf, "+\n", sizeof buf)) {
152 			char *ypbuf, *ypdom;
153 			int ypbuflen;
154 
155 			if (yp_get_default_domain(&ypdom))
156 				continue;
157 			if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
158 			    &ypbuf, &ypbuflen))
159 				continue;
160 			if (ether_line(ypbuf, e, try) == 0) {
161 				free(ypbuf);
162 				(void)fclose(f);
163 				return 0;
164 			}
165 			free(ypbuf);
166 			continue;
167 		}
168 #endif
169 		if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
170 			(void)fclose(f);
171 			return 0;
172 		}
173 	}
174 	(void)fclose(f);
175 	errno = ENOENT;
176 	return -1;
177 }
178 
179 int
180 ether_line(l, e, hostname)
181 	char *l;
182 	struct ether_addr *e;
183 	char *hostname;
184 {
185 	u_int i[6];
186 
187 	if (sscanf(l, " %x:%x:%x:%x:%x:%x %s\n", &i[0], &i[1],
188 	    &i[2], &i[3], &i[4], &i[5], hostname) == 7) {
189 		e->ether_addr_octet[0] = (u_char)i[0];
190 		e->ether_addr_octet[1] = (u_char)i[1];
191 		e->ether_addr_octet[2] = (u_char)i[2];
192 		e->ether_addr_octet[3] = (u_char)i[3];
193 		e->ether_addr_octet[4] = (u_char)i[4];
194 		e->ether_addr_octet[5] = (u_char)i[5];
195 		return 0;
196 	}
197 	errno = EINVAL;
198 	return -1;
199 }
200