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