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