etherent.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (c) 1990, 1993, 1994, 1995, 1996
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that: (1) source code distributions
  7. * retain the above copyright notice and this paragraph in its entirety, (2)
  8. * distributions including binary code include the above copyright notice and
  9. * this paragraph in its entirety in the documentation or other materials
  10. * provided with the distribution, and (3) all advertising materials mentioning
  11. * features or use of this software display the following acknowledgement:
  12. * ``This product includes software developed by the University of California,
  13. * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14. * the University nor the names of its contributors may be used to endorse
  15. * or promote products derived from this software without specific prior
  16. * written permission.
  17. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <pcap-types.h>
  25. #include <ctype.h>
  26. #include <memory.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include "pcap-int.h"
  30. #include <pcap/namedb.h>
  31. #ifdef HAVE_OS_PROTO_H
  32. #include "os-proto.h"
  33. #endif
  34. static inline int skip_space(FILE *);
  35. static inline int skip_line(FILE *);
  36. /* Hex digit to integer. */
  37. static inline u_char
  38. xdtoi(u_char c)
  39. {
  40. if (isdigit(c))
  41. return (u_char)(c - '0');
  42. else if (islower(c))
  43. return (u_char)(c - 'a' + 10);
  44. else
  45. return (u_char)(c - 'A' + 10);
  46. }
  47. static inline int
  48. skip_space(FILE *f)
  49. {
  50. int c;
  51. do {
  52. c = getc(f);
  53. } while (isspace(c) && c != '\n');
  54. return c;
  55. }
  56. static inline int
  57. skip_line(FILE *f)
  58. {
  59. int c;
  60. do
  61. c = getc(f);
  62. while (c != '\n' && c != EOF);
  63. return c;
  64. }
  65. struct pcap_etherent *
  66. pcap_next_etherent(FILE *fp)
  67. {
  68. register int c, i;
  69. u_char d;
  70. char *bp;
  71. size_t namesize;
  72. static struct pcap_etherent e;
  73. memset((char *)&e, 0, sizeof(e));
  74. for (;;) {
  75. /* Find addr */
  76. c = skip_space(fp);
  77. if (c == EOF)
  78. return (NULL);
  79. if (c == '\n')
  80. continue;
  81. /* If this is a comment, or first thing on line
  82. cannot be Ethernet address, skip the line. */
  83. if (!isxdigit(c)) {
  84. c = skip_line(fp);
  85. if (c == EOF)
  86. return (NULL);
  87. continue;
  88. }
  89. /* must be the start of an address */
  90. for (i = 0; i < 6; i += 1) {
  91. d = xdtoi((u_char)c);
  92. c = getc(fp);
  93. if (c == EOF)
  94. return (NULL);
  95. if (isxdigit(c)) {
  96. d <<= 4;
  97. d |= xdtoi((u_char)c);
  98. c = getc(fp);
  99. if (c == EOF)
  100. return (NULL);
  101. }
  102. e.addr[i] = d;
  103. if (c != ':')
  104. break;
  105. c = getc(fp);
  106. if (c == EOF)
  107. return (NULL);
  108. }
  109. /* Must be whitespace */
  110. if (!isspace(c)) {
  111. c = skip_line(fp);
  112. if (c == EOF)
  113. return (NULL);
  114. continue;
  115. }
  116. c = skip_space(fp);
  117. if (c == EOF)
  118. return (NULL);
  119. /* hit end of line... */
  120. if (c == '\n')
  121. continue;
  122. if (c == '#') {
  123. c = skip_line(fp);
  124. if (c == EOF)
  125. return (NULL);
  126. continue;
  127. }
  128. /* pick up name */
  129. bp = e.name;
  130. /* Use 'namesize' to prevent buffer overflow. */
  131. namesize = sizeof(e.name) - 1;
  132. do {
  133. *bp++ = (u_char)c;
  134. c = getc(fp);
  135. if (c == EOF)
  136. return (NULL);
  137. } while (!isspace(c) && --namesize != 0);
  138. *bp = '\0';
  139. /* Eat trailing junk */
  140. if (c != '\n')
  141. (void)skip_line(fp);
  142. return &e;
  143. }
  144. }