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