Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. host.c
  5. Abstract:
  6. etc/hosts parser
  7. Author:
  8. Jiandong Ruan
  9. Revision History:
  10. Feb-15-2001 First functional version
  11. --*/
  12. #include "precomp.h"
  13. #include "fileio.h"
  14. #include "debug.h"
  15. #define IS_VALID_HOSTNAME_CHAR(ch) \
  16. (((ch) >= 'a' && (ch) <= 'z') || ((ch) == '.') || \
  17. ((ch) >= 'A' && (ch) <= 'Z') || \
  18. ((ch) >= '0' && (ch) <= '9') || \
  19. ((ch) == '_') || ((ch) == '-'))
  20. #define IS_VALID_IPADDR_CHAR(ch) \
  21. (((ch) >= '0' && (ch) <= '9') || \
  22. ((ch) >= 'a' && (ch) <= 'f') || \
  23. ((ch) >= 'A' && (ch) <= 'F') || \
  24. ((ch) == '.') || ((ch) == ':'))
  25. #define ISSPACE(ch) \
  26. (((ch) == ' ') || ((ch) == '\t'))
  27. #define ISNEWLINE(ch) \
  28. (((ch) == '\r') || ((ch) == '\n'))
  29. #define NEXT_LINE() \
  30. do { \
  31. while (ch != EOF && !ISNEWLINE(ch)) { \
  32. ch = Smb_fgetc(fp); \
  33. } \
  34. while (ISNEWLINE(ch)) { \
  35. ch = Smb_fgetc(fp); \
  36. } \
  37. } while (0)
  38. #define SKIP_SPACE() \
  39. do { \
  40. while (ISSPACE(ch)) { \
  41. ch = Smb_fgetc(fp); \
  42. } \
  43. } while(0)
  44. #define SKIP_EMPTY_LINE() \
  45. do { \
  46. while (ISNEWLINE(ch)) { \
  47. ch = Smb_fgetc(fp); \
  48. } \
  49. } while(0)
  50. #define SMB_MAX_HOST_NAME_SIZE 256
  51. #define SMB_MAX_IPADDR_SIZE 40
  52. BOOL
  53. SmbLookupHost(
  54. WCHAR *host,
  55. PSMB_IP_ADDRESS ipaddr
  56. )
  57. {
  58. PSMB_FILE fp;
  59. int ch;
  60. int addr_size, name_size;
  61. CHAR addr[SMB_MAX_IPADDR_SIZE];
  62. CHAR name[SMB_MAX_HOST_NAME_SIZE];
  63. UNICODE_STRING ucHost;
  64. ANSI_STRING oemHost, oemName, oemAddr;
  65. NTSTATUS status;
  66. //
  67. // We need to test it in user mode. PAGED_CODE() import KeGetCurrentIrql() which
  68. // cannot be provided by user mode
  69. //
  70. //PAGED_CODE();
  71. fp = NULL;
  72. oemHost.Buffer = NULL;
  73. fp = Smb_fopen(L"\\SystemRoot\\System32\\drivers\\etc\\hosts", L"r");
  74. if (fp == NULL) {
  75. return FALSE;
  76. }
  77. RtlInitUnicodeString(&ucHost, host);
  78. status = RtlUnicodeStringToAnsiString(&oemHost, &ucHost, TRUE);
  79. BAIL_OUT_ON_ERROR(status);
  80. ch = Smb_fgetc(fp);
  81. while(ch != EOF) {
  82. SKIP_EMPTY_LINE();
  83. SKIP_SPACE();
  84. if (ch == '#') {
  85. //
  86. // This is comment, skip to the next line
  87. //
  88. NEXT_LINE();
  89. continue;
  90. }
  91. if (ch == EOF) {
  92. break;
  93. }
  94. //
  95. // Parse this entry
  96. // ipaddr host-name
  97. //
  98. //
  99. // parse the ipaddr
  100. //
  101. addr_size = 0;
  102. while (IS_VALID_IPADDR_CHAR(ch)) {
  103. addr[addr_size++] = (CHAR)ch;
  104. ch = Smb_fgetc(fp);
  105. if (addr_size >= SMB_MAX_IPADDR_SIZE) {
  106. break;
  107. }
  108. }
  109. if (addr_size >= SMB_MAX_IPADDR_SIZE || !ISSPACE(ch)) {
  110. NEXT_LINE();
  111. continue;
  112. }
  113. addr[addr_size] = '\0';
  114. //
  115. // parse the host-name
  116. //
  117. SKIP_SPACE();
  118. name_size = 0;
  119. while (IS_VALID_HOSTNAME_CHAR(ch)) {
  120. name[name_size++] = (CHAR)ch;
  121. ch = Smb_fgetc(fp);
  122. if (name_size >= SMB_MAX_IPADDR_SIZE) {
  123. break;
  124. }
  125. }
  126. if (name_size >= SMB_MAX_HOST_NAME_SIZE || (ch != EOF && !ISSPACE(ch) && ch != '#' && !ISNEWLINE(ch))) {
  127. NEXT_LINE();
  128. continue;
  129. }
  130. name[name_size] = '\0';
  131. //
  132. // Compare
  133. //
  134. RtlInitAnsiString(&oemName, name);
  135. if (RtlCompareString(&oemName, &oemHost, TRUE) == 0) {
  136. UNICODE_STRING ucAddr;
  137. RtlInitAnsiString(&oemAddr, addr);
  138. status = RtlAnsiStringToUnicodeString(&ucAddr, &oemAddr, TRUE);
  139. BAIL_OUT_ON_ERROR(status);
  140. //
  141. // Check if it is an IPv6 format
  142. //
  143. if (inet_addr6W(ucAddr.Buffer, &ipaddr->ip6)) {
  144. RtlFreeUnicodeString(&ucAddr);
  145. RtlFreeAnsiString(&oemHost);
  146. Smb_fclose(fp);
  147. ipaddr->sin_family = SMB_AF_INET6;
  148. return TRUE;
  149. }
  150. //
  151. // Check if it is an IPv4 format
  152. //
  153. ipaddr->ip4.sin4_addr = inet_addrW(ucAddr.Buffer);
  154. if (ipaddr->ip4.sin4_addr != INADDR_NONE) {
  155. RtlFreeUnicodeString(&ucAddr);
  156. RtlFreeAnsiString(&oemHost);
  157. Smb_fclose(fp);
  158. ipaddr->sin_family = SMB_AF_INET;
  159. return TRUE;
  160. }
  161. RtlFreeUnicodeString(&ucAddr);
  162. }
  163. }
  164. cleanup:
  165. if (fp) {
  166. Smb_fclose(fp);
  167. }
  168. if (oemHost.Buffer) {
  169. RtlFreeAnsiString(&oemHost);
  170. }
  171. return FALSE;
  172. }