ethers.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * libc/inet/ethers.c
  3. *
  4. * Programmatic interface for the /etc/ethers file
  5. *
  6. * Copyright 2007 by Matthew Wilcox <matthew@wil.cx>
  7. *
  8. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  9. */
  10. #include <ctype.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <netinet/ether.h>
  14. #define ETHER_LINE_LEN 256
  15. /*
  16. * Internal function which returns a pointer to the part of the line
  17. * with the start of the hostname, or NULL if we couldn't parse the line.
  18. * Note that this line may have a comment symbol on it somewhere; if so
  19. * it will return NULL if the # is before or within the ether_addr, and
  20. * succeed if the # is before or within the host. It's up to the callers
  21. * to be aware of this.
  22. *
  23. * I would have preferred to write a NUL to the location of the comment
  24. * character, but ether_line takes a const argument. See __ether_line_w.
  25. */
  26. static const char *__ether_line(const char *line, struct ether_addr *addr)
  27. {
  28. struct ether_addr *res = ether_aton_r(line, addr);
  29. if (!res)
  30. return NULL;
  31. while (*line && (*line != ' ') && (*line != '\t'))
  32. line++;
  33. while (*line && ((*line == ' ') || (*line == '\t')))
  34. line++;
  35. return (*line) ? line : NULL;
  36. }
  37. /*
  38. * Strips out the comment before calling __ether_line. We can do this,
  39. * since we know the buffer is writable.
  40. */
  41. static const char *__ether_line_w(char *line, struct ether_addr *addr)
  42. {
  43. char *end = strchr(line, '#');
  44. if (!end)
  45. end = strchr(line, '\n');
  46. if (end)
  47. *end = '\0';
  48. return __ether_line(line, addr);
  49. }
  50. int ether_line(const char *line, struct ether_addr *addr, char *hostname)
  51. {
  52. const char *name = __ether_line(line, addr);
  53. if (!name)
  54. return -1;
  55. while (*name) {
  56. if ((*name == '#') || isspace(*name))
  57. break;
  58. *hostname++ = *name++;
  59. }
  60. *hostname = '\0';
  61. return 0;
  62. }
  63. int ether_ntohost(char *hostname, const struct ether_addr *addr)
  64. {
  65. int res = -1;
  66. FILE *fp;
  67. char buf[ETHER_LINE_LEN];
  68. fp = fopen(ETHER_FILE_NAME, "r");
  69. if (!fp)
  70. return -1;
  71. while (fgets(buf, sizeof(buf), fp)) {
  72. struct ether_addr tmp_addr;
  73. const char *cp = __ether_line_w(buf, &tmp_addr);
  74. if (!cp)
  75. continue;
  76. if (memcmp(addr, &tmp_addr, sizeof(tmp_addr)))
  77. continue;
  78. strcpy(hostname, cp);
  79. res = 0;
  80. break;
  81. }
  82. fclose(fp);
  83. return res;
  84. }
  85. int ether_hostton(const char *hostname, struct ether_addr *addr)
  86. {
  87. int res = -1;
  88. FILE *fp;
  89. char buf[ETHER_LINE_LEN];
  90. fp = fopen(ETHER_FILE_NAME, "r");
  91. if (!fp)
  92. return -1;
  93. while (fgets(buf, sizeof(buf), fp)) {
  94. const char *cp = __ether_line_w(buf, addr);
  95. if (!cp)
  96. continue;
  97. if (strcasecmp(hostname, cp))
  98. continue;
  99. res = 0;
  100. break;
  101. }
  102. fclose(fp);
  103. return res;
  104. }