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.

258 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. ip2netbios.c
  5. Abstract:
  6. Generate a Netbios name for IPv6 address
  7. srv.sys cannot handle IPv6 address. It always expect a 15 characters Netbios name.
  8. This is a temporary solution. The utilmate solution should be in srv.
  9. Author:
  10. Jiandong Ruan
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. struct SMB_IPV6_NETBIOS_TABLE {
  15. PSMB_HASH_TABLE HashTable;
  16. DWORD SerialNumber;
  17. #ifndef NO_LOOKASIDE_LIST
  18. NPAGED_LOOKASIDE_LIST LookasideList;
  19. BOOL LookasideListInitialized;
  20. #endif
  21. } SmbIPv6Mapping;
  22. typedef struct {
  23. LIST_ENTRY Linkage;
  24. BYTE IpAddress[16];
  25. LONG RefCount;
  26. DWORD Serial;
  27. } SMB_IPV6_NETBIOS, *PSMB_IPV6_NETBIOS;
  28. #define SMB_IPV6_NETBIOS_TAG 'MBMS'
  29. #ifdef NO_LOOKASIDE_LIST
  30. PSMB_IPV6_NETBIOS __inline SMB_NEW_MAPPING(VOID)
  31. {
  32. return ExAllocatePoolWithTag(NonPagedPool, sizeof(SMB_IPV6_NETBIOS), SMB_IPV6_NETBIOS_TAG);
  33. }
  34. VOID __inline SMB_FREE_MAPPING(PSMB_IPV6_NETBIOS mapping)
  35. {
  36. ExFreePool(mapping);
  37. }
  38. #else
  39. PSMB_IPV6_NETBIOS __inline SMB_NEW_MAPPING(VOID)
  40. {
  41. return ExAllocateFromNPagedLookasideList(&SmbIPv6Mapping.LookasideList);
  42. }
  43. VOID __inline SMB_FREE_MAPPING(PSMB_IPV6_NETBIOS mapping)
  44. {
  45. ExFreeToNPagedLookasideList(&SmbIPv6Mapping.LookasideList, mapping);
  46. }
  47. #endif
  48. static PVOID __inline
  49. SmbIPv6MapGetIpAddress(
  50. PLIST_ENTRY entry
  51. )
  52. {
  53. PSMB_IPV6_NETBIOS mapping = NULL;
  54. mapping = CONTAINING_RECORD(entry, SMB_IPV6_NETBIOS, Linkage);
  55. return mapping->IpAddress;
  56. }
  57. static int
  58. SmbCompareIPv6Address(
  59. PLIST_ENTRY entry,
  60. BYTE ip6[16]
  61. )
  62. {
  63. return memcmp(SmbIPv6MapGetIpAddress(entry), ip6, 16);
  64. }
  65. static DWORD
  66. SmbHashIPv6(BYTE ip6[16])
  67. {
  68. DWORD sum = 0;
  69. int i;
  70. for (sum = 0, i = 0; i < 16; i++) {
  71. sum += ip6[i];
  72. }
  73. return sum;
  74. }
  75. static VOID
  76. SmbOnAddMapping(
  77. PLIST_ENTRY entry
  78. )
  79. {
  80. PSMB_IPV6_NETBIOS mapping = NULL;
  81. mapping = CONTAINING_RECORD(entry, SMB_IPV6_NETBIOS, Linkage);
  82. mapping->Serial = InterlockedIncrement(&SmbIPv6Mapping.SerialNumber);
  83. mapping->RefCount = 1;
  84. }
  85. static VOID
  86. SmbOnDelMapping(
  87. PLIST_ENTRY entry
  88. )
  89. {
  90. PSMB_IPV6_NETBIOS mapping = NULL;
  91. mapping = CONTAINING_RECORD(entry, SMB_IPV6_NETBIOS, Linkage);
  92. ASSERT(mapping->RefCount == 0);
  93. SMB_FREE_MAPPING(mapping);
  94. }
  95. static LONG
  96. SmbReferenceMapping(
  97. PLIST_ENTRY entry
  98. )
  99. {
  100. PSMB_IPV6_NETBIOS mapping = NULL;
  101. LONG RefCount;
  102. mapping = CONTAINING_RECORD(entry, SMB_IPV6_NETBIOS, Linkage);
  103. RefCount = InterlockedIncrement(&mapping->RefCount);
  104. ASSERT(RefCount > 1);
  105. return RefCount;
  106. }
  107. static LONG
  108. SmbDereferenceMapping(
  109. PLIST_ENTRY entry
  110. )
  111. {
  112. PSMB_IPV6_NETBIOS mapping = NULL;
  113. LONG RefCount;
  114. mapping = CONTAINING_RECORD(entry, SMB_IPV6_NETBIOS, Linkage);
  115. RefCount = InterlockedDecrement(&mapping->RefCount);
  116. ASSERT(RefCount >= 0);
  117. return RefCount;
  118. }
  119. NTSTATUS
  120. SmbInitIPv6NetbiosMappingTable(
  121. VOID
  122. )
  123. {
  124. NTSTATUS status = STATUS_SUCCESS;
  125. RtlZeroMemory(&SmbIPv6Mapping, sizeof(SmbIPv6Mapping));
  126. SmbIPv6Mapping.HashTable =
  127. SmbCreateHashTable(
  128. 256,
  129. SmbHashIPv6,
  130. SmbIPv6MapGetIpAddress,
  131. SmbCompareIPv6Address,
  132. SmbOnAddMapping,
  133. SmbOnDelMapping,
  134. SmbReferenceMapping,
  135. SmbDereferenceMapping
  136. );
  137. if (NULL == SmbIPv6Mapping.HashTable) {
  138. status = STATUS_INSUFFICIENT_RESOURCES;
  139. goto error;
  140. }
  141. SmbIPv6Mapping.SerialNumber = 0;
  142. #ifndef NO_LOOKASIDE_LIST
  143. ExInitializeNPagedLookasideList(
  144. &SmbIPv6Mapping.LookasideList,
  145. NULL,
  146. NULL,
  147. 0,
  148. sizeof(SMB_IPV6_NETBIOS),
  149. SMB_IPV6_NETBIOS_TAG,
  150. 0
  151. );
  152. SmbIPv6Mapping.LookasideListInitialized = TRUE;
  153. #endif
  154. error:
  155. return status;
  156. }
  157. VOID
  158. SmbShutdownIPv6NetbiosMappingTable(
  159. VOID
  160. )
  161. {
  162. SmbDestroyHashTable(SmbIPv6Mapping.HashTable);
  163. SmbIPv6Mapping.HashTable = NULL;
  164. #ifndef NO_LOOKASIDE_LIST
  165. if (SmbIPv6Mapping.LookasideListInitialized) {
  166. ExDeleteNPagedLookasideList(&SmbIPv6Mapping.LookasideList);
  167. SmbIPv6Mapping.LookasideListInitialized = FALSE;
  168. }
  169. #endif
  170. }
  171. #define xdigit2asc(x) ((CHAR)(((x) < 10)?((x)+'0'):((x)+'0' + 'a' - '9' - 1)))
  172. static void
  173. UlongToHex(
  174. ULONG x,
  175. CHAR *Buffer
  176. )
  177. {
  178. Buffer[0] = xdigit2asc((x >> 28) & 0xf);
  179. Buffer[1] = xdigit2asc((x >> 24) & 0xf);
  180. Buffer[2] = xdigit2asc((x >> 20) & 0xf);
  181. Buffer[3] = xdigit2asc((x >> 16) & 0xf);
  182. Buffer[4] = xdigit2asc((x >> 12) & 0xf);
  183. Buffer[5] = xdigit2asc((x >> 8) & 0xf);
  184. Buffer[6] = xdigit2asc((x >> 4) & 0xf);
  185. Buffer[7] = xdigit2asc(x & 0xf);
  186. Buffer[8] = 0;
  187. }
  188. BOOL
  189. GetNetbiosNameFromIp6Address(BYTE ip6[16], CHAR SmbName[16])
  190. {
  191. PSMB_IPV6_NETBIOS NewMapping = NULL;
  192. PLIST_ENTRY FoundEntry = NULL, NewEntry = NULL;
  193. NewMapping = SMB_NEW_MAPPING();
  194. if (NULL == NewMapping) {
  195. return FALSE;
  196. }
  197. NewEntry = &NewMapping->Linkage;
  198. RtlCopyMemory(NewMapping->IpAddress, ip6, 16);
  199. FoundEntry = SmbAddToHashTable(SmbIPv6Mapping.HashTable, NewEntry);
  200. if (FoundEntry != NewEntry) {
  201. SMB_FREE_MAPPING(NewMapping);
  202. NewMapping = NULL;
  203. NewEntry = NULL;
  204. }
  205. NewMapping = CONTAINING_RECORD(FoundEntry, SMB_IPV6_NETBIOS, Linkage);
  206. RtlCopyMemory(SmbName, "*SMBSERVER ", 7);
  207. UlongToHex(NewMapping->Serial, SmbName + 7);
  208. return TRUE;
  209. }
  210. VOID
  211. FreeNetbiosNameForIp6Address(BYTE ip6[16])
  212. {
  213. SmbRemoveFromHashTable(SmbIPv6Mapping.HashTable, ip6);
  214. }