1 1.25 christos /* $NetBSD: ethers.c,v 1.25 2014/09/18 13:58:20 christos Exp $ */ 2 1.5 cgd 3 1.1 deraadt /* 4 1.1 deraadt * ethers(3N) a la Sun. 5 1.1 deraadt * 6 1.1 deraadt * Written by Roland McGrath <roland (at) frob.com> 10/14/93. 7 1.1 deraadt * Public domain. 8 1.1 deraadt */ 9 1.18 itojun 10 1.18 itojun #include <sys/cdefs.h> 11 1.18 itojun #if defined(LIBC_SCCS) && !defined(lint) 12 1.25 christos __RCSID("$NetBSD: ethers.c,v 1.25 2014/09/18 13:58:20 christos Exp $"); 13 1.18 itojun #endif /* LIBC_SCCS and not lint */ 14 1.1 deraadt 15 1.10 jtc #include "namespace.h" 16 1.15 lukem #include <sys/param.h> 17 1.1 deraadt #include <sys/socket.h> 18 1.15 lukem 19 1.1 deraadt #include <net/if.h> 20 1.8 is #include <net/if_ether.h> 21 1.1 deraadt #include <netinet/in.h> 22 1.15 lukem 23 1.15 lukem #include <assert.h> 24 1.15 lukem #include <errno.h> 25 1.1 deraadt #include <paths.h> 26 1.1 deraadt #include <stdio.h> 27 1.3 jtc #include <stdlib.h> 28 1.3 jtc #include <string.h> 29 1.15 lukem 30 1.9 christos #ifdef YP 31 1.9 christos #include <rpcsvc/ypclnt.h> 32 1.10 jtc #endif 33 1.10 jtc 34 1.10 jtc #ifdef __weak_alias 35 1.17 mycroft __weak_alias(ether_aton,_ether_aton) 36 1.17 mycroft __weak_alias(ether_hostton,_ether_hostton) 37 1.17 mycroft __weak_alias(ether_line,_ether_line) 38 1.17 mycroft __weak_alias(ether_ntoa,_ether_ntoa) 39 1.17 mycroft __weak_alias(ether_ntohost,_ether_ntohost) 40 1.9 christos #endif 41 1.1 deraadt 42 1.1 deraadt #ifndef _PATH_ETHERS 43 1.1 deraadt #define _PATH_ETHERS "/etc/ethers" 44 1.1 deraadt #endif 45 1.1 deraadt 46 1.1 deraadt char * 47 1.23 matt ether_ntoa(const struct ether_addr *e) 48 1.1 deraadt { 49 1.13 mycroft static char a[18]; 50 1.1 deraadt 51 1.15 lukem _DIAGASSERT(e != NULL); 52 1.15 lukem 53 1.20 tron (void) snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x", 54 1.1 deraadt e->ether_addr_octet[0], e->ether_addr_octet[1], 55 1.1 deraadt e->ether_addr_octet[2], e->ether_addr_octet[3], 56 1.1 deraadt e->ether_addr_octet[4], e->ether_addr_octet[5]); 57 1.1 deraadt return a; 58 1.1 deraadt } 59 1.1 deraadt 60 1.1 deraadt struct ether_addr * 61 1.23 matt ether_aton(const char *s) 62 1.1 deraadt { 63 1.1 deraadt static struct ether_addr n; 64 1.1 deraadt u_int i[6]; 65 1.1 deraadt 66 1.15 lukem _DIAGASSERT(s != NULL); 67 1.15 lukem 68 1.1 deraadt if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1], 69 1.1 deraadt &i[2], &i[3], &i[4], &i[5]) == 6) { 70 1.1 deraadt n.ether_addr_octet[0] = (u_char)i[0]; 71 1.1 deraadt n.ether_addr_octet[1] = (u_char)i[1]; 72 1.1 deraadt n.ether_addr_octet[2] = (u_char)i[2]; 73 1.1 deraadt n.ether_addr_octet[3] = (u_char)i[3]; 74 1.1 deraadt n.ether_addr_octet[4] = (u_char)i[4]; 75 1.1 deraadt n.ether_addr_octet[5] = (u_char)i[5]; 76 1.1 deraadt return &n; 77 1.1 deraadt } 78 1.1 deraadt return NULL; 79 1.1 deraadt } 80 1.1 deraadt 81 1.6 mikel int 82 1.23 matt ether_ntohost(char *hostname, const struct ether_addr *e) 83 1.1 deraadt { 84 1.1 deraadt FILE *f; 85 1.11 lukem char *p; 86 1.1 deraadt struct ether_addr try; 87 1.1 deraadt 88 1.15 lukem _DIAGASSERT(hostname != NULL); 89 1.15 lukem _DIAGASSERT(e != NULL); 90 1.15 lukem 91 1.15 lukem #ifdef YP 92 1.24 christos char trybuf[sizeof "xx:xx:xx:xx:xx:xx"]; 93 1.24 christos int trylen; 94 1.11 lukem trylen = snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x", 95 1.1 deraadt e->ether_addr_octet[0], e->ether_addr_octet[1], 96 1.1 deraadt e->ether_addr_octet[2], e->ether_addr_octet[3], 97 1.1 deraadt e->ether_addr_octet[4], e->ether_addr_octet[5]); 98 1.1 deraadt #endif 99 1.1 deraadt 100 1.25 christos f = fopen(_PATH_ETHERS, "re"); 101 1.11 lukem if (f == NULL) 102 1.1 deraadt return -1; 103 1.24 christos for (p = NULL;;) { 104 1.24 christos free(p); 105 1.24 christos p = fparseln(f, NULL, NULL, NULL, FPARSELN_UNESCALL); 106 1.24 christos if (p == NULL) 107 1.24 christos break; 108 1.1 deraadt #ifdef YP 109 1.1 deraadt /* A + in the file means try YP now. */ 110 1.24 christos if (strcmp(p, "+") == 0) { 111 1.1 deraadt char *ypbuf, *ypdom; 112 1.1 deraadt int ypbuflen; 113 1.1 deraadt 114 1.1 deraadt if (yp_get_default_domain(&ypdom)) 115 1.1 deraadt continue; 116 1.1 deraadt if (yp_match(ypdom, "ethers.byaddr", trybuf, 117 1.1 deraadt trylen, &ypbuf, &ypbuflen)) 118 1.1 deraadt continue; 119 1.24 christos ypbuflen = ether_line(ypbuf, &try, hostname); 120 1.1 deraadt free(ypbuf); 121 1.24 christos if (ypbuflen == 0) 122 1.24 christos goto done; 123 1.2 deraadt continue; 124 1.1 deraadt } 125 1.1 deraadt #endif 126 1.11 lukem if (ether_line(p, &try, hostname) == 0 && 127 1.24 christos memcmp(&try, e, sizeof try) == 0) 128 1.24 christos goto done; 129 1.1 deraadt } 130 1.24 christos free(p); 131 1.1 deraadt (void)fclose(f); 132 1.1 deraadt errno = ENOENT; 133 1.1 deraadt return -1; 134 1.24 christos done: 135 1.24 christos free(p); 136 1.24 christos (void)fclose(f); 137 1.24 christos return 0; 138 1.1 deraadt } 139 1.1 deraadt 140 1.6 mikel int 141 1.23 matt ether_hostton(const char *hostname, struct ether_addr *e) 142 1.1 deraadt { 143 1.1 deraadt FILE *f; 144 1.11 lukem char *p; 145 1.11 lukem char try[MAXHOSTNAMELEN + 1]; 146 1.1 deraadt #ifdef YP 147 1.22 christos int hostlen = (int)strlen(hostname); 148 1.1 deraadt #endif 149 1.1 deraadt 150 1.15 lukem _DIAGASSERT(hostname != NULL); 151 1.15 lukem _DIAGASSERT(e != NULL); 152 1.15 lukem 153 1.25 christos f = fopen(_PATH_ETHERS, "re"); 154 1.24 christos if (f == NULL) 155 1.1 deraadt return -1; 156 1.1 deraadt 157 1.24 christos for (p = NULL;;) { 158 1.24 christos free(p); 159 1.24 christos p = fparseln(f, NULL, NULL, NULL, FPARSELN_UNESCALL); 160 1.24 christos if (p == NULL) 161 1.24 christos break; 162 1.1 deraadt #ifdef YP 163 1.1 deraadt /* A + in the file means try YP now. */ 164 1.24 christos if (strcmp(p, "+") == 0) { 165 1.1 deraadt char *ypbuf, *ypdom; 166 1.1 deraadt int ypbuflen; 167 1.1 deraadt 168 1.1 deraadt if (yp_get_default_domain(&ypdom)) 169 1.1 deraadt continue; 170 1.1 deraadt if (yp_match(ypdom, "ethers.byname", hostname, hostlen, 171 1.1 deraadt &ypbuf, &ypbuflen)) 172 1.1 deraadt continue; 173 1.24 christos ypbuflen = ether_line(ypbuf, e, try); 174 1.1 deraadt free(ypbuf); 175 1.24 christos if (ypbuflen == 0) 176 1.24 christos goto done; 177 1.2 deraadt continue; 178 1.1 deraadt } 179 1.1 deraadt #endif 180 1.24 christos if (ether_line(p, e, try) == 0 && strcmp(hostname, try) == 0) 181 1.24 christos goto done; 182 1.1 deraadt } 183 1.24 christos free(p); 184 1.1 deraadt (void)fclose(f); 185 1.1 deraadt errno = ENOENT; 186 1.1 deraadt return -1; 187 1.24 christos done: 188 1.24 christos free(p); 189 1.24 christos (void)fclose(f); 190 1.24 christos return 0; 191 1.1 deraadt } 192 1.1 deraadt 193 1.6 mikel int 194 1.23 matt ether_line(const char *l, struct ether_addr *e, char *hostname) 195 1.1 deraadt { 196 1.1 deraadt u_int i[6]; 197 1.15 lukem 198 1.19 sommerfe #define S2(arg) #arg 199 1.19 sommerfe #define S1(arg) S2(arg) 200 1.21 martin static const char fmt[] = " %x:%x:%x:%x:%x:%x" 201 1.19 sommerfe " %" S1(MAXHOSTNAMELEN) "s\n"; 202 1.19 sommerfe #undef S2 203 1.19 sommerfe #undef S1 204 1.19 sommerfe 205 1.15 lukem _DIAGASSERT(l != NULL); 206 1.15 lukem _DIAGASSERT(e != NULL); 207 1.15 lukem _DIAGASSERT(hostname != NULL); 208 1.1 deraadt 209 1.19 sommerfe if (sscanf(l, fmt, 210 1.11 lukem &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], hostname) == 7) { 211 1.1 deraadt e->ether_addr_octet[0] = (u_char)i[0]; 212 1.1 deraadt e->ether_addr_octet[1] = (u_char)i[1]; 213 1.1 deraadt e->ether_addr_octet[2] = (u_char)i[2]; 214 1.1 deraadt e->ether_addr_octet[3] = (u_char)i[3]; 215 1.1 deraadt e->ether_addr_octet[4] = (u_char)i[4]; 216 1.1 deraadt e->ether_addr_octet[5] = (u_char)i[5]; 217 1.1 deraadt return 0; 218 1.1 deraadt } 219 1.1 deraadt errno = EINVAL; 220 1.1 deraadt return -1; 221 1.1 deraadt } 222