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