lib/libc/net/ethers.c

http://www.minix3.org/ · C · 230 lines · 193 code · 28 blank · 9 comment · 48 complexity · 093e49bd117652c35e46ee8c65d88aea MD5 · raw file

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